summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'source/core')
-rw-r--r--source/core/slang-allocator.h112
-rw-r--r--source/core/slang-archive-file-system.cpp33
-rw-r--r--source/core/slang-archive-file-system.h36
-rw-r--r--source/core/slang-array-view.h329
-rw-r--r--source/core/slang-array.h395
-rw-r--r--source/core/slang-basic.h10
-rw-r--r--source/core/slang-blob.cpp34
-rw-r--r--source/core/slang-blob.h166
-rw-r--r--source/core/slang-byte-encode-util.cpp78
-rw-r--r--source/core/slang-byte-encode-util.h139
-rw-r--r--source/core/slang-castable.cpp8
-rw-r--r--source/core/slang-castable.h81
-rw-r--r--source/core/slang-char-encode.cpp192
-rw-r--r--source/core/slang-char-encode.h57
-rw-r--r--source/core/slang-char-util.cpp9
-rw-r--r--source/core/slang-char-util.h93
-rw-r--r--source/core/slang-chunked-list.h37
-rw-r--r--source/core/slang-com-object.h68
-rw-r--r--source/core/slang-command-line.cpp12
-rw-r--r--source/core/slang-command-line.h113
-rw-r--r--source/core/slang-command-options-writer.cpp192
-rw-r--r--source/core/slang-command-options-writer.h37
-rw-r--r--source/core/slang-command-options.cpp129
-rw-r--r--source/core/slang-command-options.h237
-rw-r--r--source/core/slang-common.h289
-rw-r--r--source/core/slang-compression-system.h62
-rw-r--r--source/core/slang-crypto.cpp106
-rw-r--r--source/core/slang-crypto.h262
-rw-r--r--source/core/slang-deflate-compression-system.cpp54
-rw-r--r--source/core/slang-deflate-compression-system.h6
-rw-r--r--source/core/slang-dictionary.h1306
-rw-r--r--source/core/slang-exception.h96
-rw-r--r--source/core/slang-file-system.cpp362
-rw-r--r--source/core/slang-file-system.h303
-rw-r--r--source/core/slang-free-list.cpp324
-rw-r--r--source/core/slang-free-list.h236
-rw-r--r--source/core/slang-func-ptr.h47
-rw-r--r--source/core/slang-hash.h379
-rw-r--r--source/core/slang-hex-dump-util.cpp73
-rw-r--r--source/core/slang-hex-dump-util.h45
-rw-r--r--source/core/slang-http.cpp69
-rw-r--r--source/core/slang-http.h127
-rw-r--r--source/core/slang-implicit-directory-collector.cpp23
-rw-r--r--source/core/slang-implicit-directory-collector.h56
-rw-r--r--source/core/slang-io.cpp2085
-rw-r--r--source/core/slang-io.h548
-rw-r--r--source/core/slang-linked-list.h46
-rw-r--r--source/core/slang-list.h994
-rw-r--r--source/core/slang-lz4-compression-system.cpp55
-rw-r--r--source/core/slang-lz4-compression-system.h6
-rw-r--r--source/core/slang-math.h460
-rw-r--r--source/core/slang-memory-arena.cpp54
-rw-r--r--source/core/slang-memory-arena.h279
-rw-r--r--source/core/slang-memory-file-system.cpp61
-rw-r--r--source/core/slang-memory-file-system.h93
-rw-r--r--source/core/slang-name-value.cpp74
-rw-r--r--source/core/slang-name-value.h115
-rw-r--r--source/core/slang-offset-container.cpp31
-rw-r--r--source/core/slang-offset-container.h336
-rw-r--r--source/core/slang-performance-profiler.cpp190
-rw-r--r--source/core/slang-performance-profiler.h15
-rw-r--r--source/core/slang-persistent-cache.cpp29
-rw-r--r--source/core/slang-persistent-cache.h6
-rw-r--r--source/core/slang-platform.cpp115
-rw-r--r--source/core/slang-platform.h277
-rw-r--r--source/core/slang-process-util.cpp27
-rw-r--r--source/core/slang-process-util.h18
-rw-r--r--source/core/slang-process.h66
-rw-r--r--source/core/slang-random-generator.cpp21
-rw-r--r--source/core/slang-random-generator.h81
-rw-r--r--source/core/slang-range.h37
-rw-r--r--source/core/slang-render-api-util.cpp103
-rw-r--r--source/core/slang-render-api-util.h55
-rw-r--r--source/core/slang-riff-file-system.cpp69
-rw-r--r--source/core/slang-riff-file-system.h56
-rw-r--r--source/core/slang-riff.cpp143
-rw-r--r--source/core/slang-riff.h299
-rw-r--r--source/core/slang-rtti-info.cpp80
-rw-r--r--source/core/slang-rtti-info.h256
-rw-r--r--source/core/slang-rtti-util.cpp386
-rw-r--r--source/core/slang-rtti-util.h80
-rw-r--r--source/core/slang-secure-crt.h84
-rw-r--r--source/core/slang-semantic-version.cpp76
-rw-r--r--source/core/slang-semantic-version.h99
-rw-r--r--source/core/slang-shared-library.cpp29
-rw-r--r--source/core/slang-shared-library.h65
-rw-r--r--source/core/slang-short-list.h772
-rw-r--r--source/core/slang-signal.cpp33
-rw-r--r--source/core/slang-signal.h14
-rw-r--r--source/core/slang-smart-pointer.h518
-rw-r--r--source/core/slang-stable-hash.h128
-rw-r--r--source/core/slang-std-writers.cpp17
-rw-r--r--source/core/slang-std-writers.h33
-rw-r--r--source/core/slang-stream.cpp162
-rw-r--r--source/core/slang-stream.h211
-rw-r--r--source/core/slang-string-escape-util.cpp449
-rw-r--r--source/core/slang-string-escape-util.h110
-rw-r--r--source/core/slang-string-slice-index-map.cpp8
-rw-r--r--source/core/slang-string-slice-index-map.h50
-rw-r--r--source/core/slang-string-slice-pool.cpp39
-rw-r--r--source/core/slang-string-slice-pool.h78
-rw-r--r--source/core/slang-string-util.cpp184
-rw-r--r--source/core/slang-string-util.h276
-rw-r--r--source/core/slang-string.cpp1101
-rw-r--r--source/core/slang-string.h1514
-rw-r--r--source/core/slang-test-tool-util.cpp68
-rw-r--r--source/core/slang-test-tool-util.h76
-rw-r--r--source/core/slang-text-io.cpp137
-rw-r--r--source/core/slang-text-io.h161
-rw-r--r--source/core/slang-token-reader.cpp1194
-rw-r--r--source/core/slang-token-reader.h533
-rw-r--r--source/core/slang-type-convert-util.cpp37
-rw-r--r--source/core/slang-type-convert-util.h7
-rw-r--r--source/core/slang-type-text-util.cpp343
-rw-r--r--source/core/slang-type-text-util.h79
-rw-r--r--source/core/slang-type-traits.h82
-rw-r--r--source/core/slang-uint-set.cpp42
-rw-r--r--source/core/slang-uint-set.h114
-rw-r--r--source/core/slang-virtual-object-pool.h8
-rw-r--r--source/core/slang-writer.cpp39
-rw-r--r--source/core/slang-writer.h161
-rw-r--r--source/core/slang-zip-file-system.cpp250
-rw-r--r--source/core/slang-zip-file-system.h9
-rw-r--r--source/core/unix/slang-unix-process.cpp152
-rw-r--r--source/core/windows/slang-win-process.cpp213
125 files changed, 13096 insertions, 11127 deletions
diff --git a/source/core/slang-allocator.h b/source/core/slang-allocator.h
index 8942f993b..03cfabe40 100644
--- a/source/core/slang-allocator.h
+++ b/source/core/slang-allocator.h
@@ -5,89 +5,77 @@
#include <stdlib.h>
#ifdef _MSC_VER
-# include <malloc.h>
+#include <malloc.h>
#endif
#include <type_traits>
namespace Slang
{
- inline void* alignedAllocate(size_t size, size_t alignment)
- {
+inline void* alignedAllocate(size_t size, size_t alignment)
+{
#ifdef _MSC_VER
- return _aligned_malloc(size, alignment);
+ return _aligned_malloc(size, alignment);
#elif defined(__CYGWIN__)
- return aligned_alloc(alignment, size);
+ return aligned_alloc(alignment, size);
#else
- void* rs = nullptr;
- int succ = posix_memalign(&rs, alignment, size);
- return (succ == 0) ? rs : nullptr;
+ void* rs = nullptr;
+ int succ = posix_memalign(&rs, alignment, size);
+ return (succ == 0) ? rs : nullptr;
#endif
- }
+}
- inline void alignedDeallocate(void* ptr)
- {
+inline void alignedDeallocate(void* ptr)
+{
#ifdef _MSC_VER
- _aligned_free(ptr);
+ _aligned_free(ptr);
#else
- free(ptr);
+ free(ptr);
#endif
- }
+}
- class StandardAllocator
- {
- public:
- // not really called
- void* allocate(size_t size)
- {
- return ::malloc(size);
- }
- void deallocate(void * ptr)
- {
- return ::free(ptr);
- }
- };
+class StandardAllocator
+{
+public:
+ // not really called
+ void* allocate(size_t size) { return ::malloc(size); }
+ void deallocate(void* ptr) { return ::free(ptr); }
+};
- template<int ALIGNMENT>
- class AlignedAllocator
- {
- public:
- void* allocate(size_t size)
- {
- return alignedAllocate(size, ALIGNMENT);
- }
- void deallocate(void * ptr)
- {
- return alignedDeallocate(ptr);
- }
- };
+template<int ALIGNMENT>
+class AlignedAllocator
+{
+public:
+ void* allocate(size_t size) { return alignedAllocate(size, ALIGNMENT); }
+ void deallocate(void* ptr) { return alignedDeallocate(ptr); }
+};
- template<typename T, typename TAllocator>
- class AllocateMethod
+template<typename T, typename TAllocator>
+class AllocateMethod
+{
+public:
+ static inline T* allocateArray(Index count)
{
- public:
- static inline T* allocateArray(Index count)
+ TAllocator allocator;
+ T* rs = (T*)allocator.allocate(count * sizeof(T));
+ if (!std::is_trivially_constructible<T>::value)
{
- TAllocator allocator;
- T* rs = (T*)allocator.allocate(count * sizeof(T));
- if (!std::is_trivially_constructible<T>::value)
- {
- for (Index i = 0; i < count; i++)
- new (rs + i) T();
- }
- return rs;
+ for (Index i = 0; i < count; i++)
+ new (rs + i) T();
}
- static inline void deallocateArray(T* ptr, Index count)
+ return rs;
+ }
+ static inline void deallocateArray(T* ptr, Index count)
+ {
+ TAllocator allocator;
+ if (!std::is_trivially_destructible<T>::value)
{
- TAllocator allocator;
- if (!std::is_trivially_destructible<T>::value)
- {
- for (Index i = 0; i < count; i++)
- ptr[i].~T();
- }
- allocator.deallocate(ptr);
+ for (Index i = 0; i < count; i++)
+ ptr[i].~T();
}
- };
+ allocator.deallocate(ptr);
+ }
+};
#if 0
template<typename T>
@@ -104,6 +92,6 @@ namespace Slang
}
};
#endif
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-archive-file-system.cpp b/source/core/slang-archive-file-system.cpp
index e219fcbb5..9513e6372 100644
--- a/source/core/slang-archive-file-system.cpp
+++ b/source/core/slang-archive-file-system.cpp
@@ -1,29 +1,28 @@
#include "slang-archive-file-system.h"
+#include "../core/slang-castable.h"
+#include "slang-blob.h"
#include "slang-com-helper.h"
#include "slang-com-ptr.h"
-
-#include "../core/slang-castable.h"
-
#include "slang-io.h"
-#include "slang-string-util.h"
-#include "slang-blob.h"
-
#include "slang-riff-file-system.h"
+#include "slang-string-util.h"
// Compression systems
#include "slang-deflate-compression-system.h"
#include "slang-lz4-compression-system.h"
// Zip file system
-#include "slang-zip-file-system.h"
-
#include "slang-riff.h"
+#include "slang-zip-file-system.h"
namespace Slang
{
-SlangResult loadArchiveFileSystem(const void* data, size_t dataSizeInBytes, ComPtr<ISlangFileSystemExt>& outFileSystem)
+SlangResult loadArchiveFileSystem(
+ const void* data,
+ size_t dataSizeInBytes,
+ ComPtr<ISlangFileSystemExt>& outFileSystem)
{
ComPtr<ISlangMutableFileSystem> fileSystem;
if (ZipFileSystem::isArchive(data, dataSizeInBytes))
@@ -34,7 +33,7 @@ SlangResult loadArchiveFileSystem(const void* data, size_t dataSizeInBytes, ComP
else if (RiffFileSystem::isArchive(data, dataSizeInBytes))
{
// It's riff contained (Slang specific)
- fileSystem = new RiffFileSystem(nullptr);
+ fileSystem = new RiffFileSystem(nullptr);
}
else
{
@@ -52,26 +51,28 @@ SlangResult loadArchiveFileSystem(const void* data, size_t dataSizeInBytes, ComP
outFileSystem = fileSystem;
return SLANG_OK;
}
-
-SlangResult createArchiveFileSystem(SlangArchiveType type, ComPtr<ISlangMutableFileSystem>& outFileSystem)
+
+SlangResult createArchiveFileSystem(
+ SlangArchiveType type,
+ ComPtr<ISlangMutableFileSystem>& outFileSystem)
{
switch (type)
{
- case SLANG_ARCHIVE_TYPE_ZIP:
+ case SLANG_ARCHIVE_TYPE_ZIP:
{
return ZipFileSystem::create(outFileSystem);
}
- case SLANG_ARCHIVE_TYPE_RIFF:
+ case SLANG_ARCHIVE_TYPE_RIFF:
{
outFileSystem = new RiffFileSystem(nullptr);
return SLANG_OK;
}
- case SLANG_ARCHIVE_TYPE_RIFF_DEFLATE:
+ case SLANG_ARCHIVE_TYPE_RIFF_DEFLATE:
{
outFileSystem = new RiffFileSystem(DeflateCompressionSystem::getSingleton());
return SLANG_OK;
}
- case SLANG_ARCHIVE_TYPE_RIFF_LZ4:
+ case SLANG_ARCHIVE_TYPE_RIFF_LZ4:
{
outFileSystem = new RiffFileSystem(LZ4CompressionSystem::getSingleton());
return SLANG_OK;
diff --git a/source/core/slang-archive-file-system.h b/source/core/slang-archive-file-system.h
index 13b226019..25bac0812 100644
--- a/source/core/slang-archive-file-system.h
+++ b/source/core/slang-archive-file-system.h
@@ -2,9 +2,7 @@
#define SLANG_CORE_ARCHIVE_FILE_SYSTEM_H
#include "slang-basic.h"
-
#include "slang-com-ptr.h"
-
#include "slang-compression-system.h"
namespace Slang
@@ -12,20 +10,32 @@ namespace Slang
class IArchiveFileSystem : public ISlangCastable
{
- SLANG_COM_INTERFACE(0x5c565aac, 0xe834, 0x41fc, { 0x8b, 0xb, 0x7d, 0x4c, 0xf3, 0x8b, 0x89, 0x50 });
-
- /// Loads an archive.
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL loadArchive(const void* archive, size_t archiveSizeInBytes) = 0;
- /// Get as an archive (that can be saved to disk)
- /// NOTE! If the blob is not owned, it's contents can be invalidated by any call to a method of the file system or loss of scope
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL storeArchive(bool blobOwnsContent, ISlangBlob** outBlob) = 0;
- /// Set the compression - used for any subsequent items added
+ SLANG_COM_INTERFACE(
+ 0x5c565aac,
+ 0xe834,
+ 0x41fc,
+ {0x8b, 0xb, 0x7d, 0x4c, 0xf3, 0x8b, 0x89, 0x50});
+
+ /// Loads an archive.
+ SLANG_NO_THROW virtual SlangResult SLANG_MCALL
+ loadArchive(const void* archive, size_t archiveSizeInBytes) = 0;
+ /// Get as an archive (that can be saved to disk)
+ /// NOTE! If the blob is not owned, it's contents can be invalidated by any call to a method of
+ /// the file system or loss of scope
+ SLANG_NO_THROW virtual SlangResult SLANG_MCALL
+ storeArchive(bool blobOwnsContent, ISlangBlob** outBlob) = 0;
+ /// Set the compression - used for any subsequent items added
SLANG_NO_THROW virtual void SLANG_MCALL setCompressionStyle(const CompressionStyle& style) = 0;
};
-SlangResult loadArchiveFileSystem(const void* data, size_t dataSizeInBytes, ComPtr<ISlangFileSystemExt>& outFileSystem);
-SlangResult createArchiveFileSystem(SlangArchiveType type, ComPtr<ISlangMutableFileSystem>& outFileSystem);
+SlangResult loadArchiveFileSystem(
+ const void* data,
+ size_t dataSizeInBytes,
+ ComPtr<ISlangFileSystemExt>& outFileSystem);
+SlangResult createArchiveFileSystem(
+ SlangArchiveType type,
+ ComPtr<ISlangMutableFileSystem>& outFileSystem);
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-array-view.h b/source/core/slang-array-view.h
index 50270e0a0..21b6ce113 100644
--- a/source/core/slang-array-view.h
+++ b/source/core/slang-array-view.h
@@ -6,222 +6,225 @@
namespace Slang
{
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ConstArrayView !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ConstArrayView !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- template<typename T>
- class ConstArrayView
- {
- public:
- typedef ConstArrayView ThisType;
+template<typename T>
+class ConstArrayView
+{
+public:
+ typedef ConstArrayView ThisType;
- SLANG_FORCE_INLINE const T* begin() const { return m_buffer; }
-
- SLANG_FORCE_INLINE const T* end() const { return m_buffer + m_count; }
-
- SLANG_FORCE_INLINE Count getCount() const { return m_count; }
+ SLANG_FORCE_INLINE const T* begin() const { return m_buffer; }
- SLANG_FORCE_INLINE const T& operator [](Index idx) const
- {
- SLANG_ASSERT(idx >= 0 && idx < m_count);
- return m_buffer[idx];
- }
-
- SLANG_FORCE_INLINE const T* getBuffer() const { return m_buffer; }
-
- template<typename T2>
- Index indexOf(const T2& val) const
- {
- for (Index i = 0; i < m_count; i++)
- {
- if (m_buffer[i] == val)
- return i;
- }
- return -1;
- }
+ SLANG_FORCE_INLINE const T* end() const { return m_buffer + m_count; }
- template<typename T2>
- Index lastIndexOf(const T2& val) const
- {
- for (Index i = m_count - 1; i >= 0; i--)
- {
- if (m_buffer[i] == val)
- return i;
- }
- return -1;
- }
+ SLANG_FORCE_INLINE Count getCount() const { return m_count; }
- template<typename Func>
- Index findFirstIndex(const Func& predicate) const
- {
- for (Index i = 0; i < m_count; i++)
- {
- if (predicate(m_buffer[i]))
- return i;
- }
- return -1;
- }
+ SLANG_FORCE_INLINE const T& operator[](Index idx) const
+ {
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
+ return m_buffer[idx];
+ }
- template<typename Func>
- Index findLastIndex(const Func& predicate) const
- {
- for (Index i = m_count - 1; i >= 0; i--)
- {
- if (predicate(m_buffer[i]))
- return i;
- }
- return -1;
- }
+ SLANG_FORCE_INLINE const T* getBuffer() const { return m_buffer; }
- bool containsMemory(const ThisType& rhs) const
+ template<typename T2>
+ Index indexOf(const T2& val) const
+ {
+ for (Index i = 0; i < m_count; i++)
{
- return rhs.getBuffer() >= getBuffer() && rhs.end() <= end();
+ if (m_buffer[i] == val)
+ return i;
}
+ return -1;
+ }
- bool operator==(const ThisType& rhs) const
+ template<typename T2>
+ Index lastIndexOf(const T2& val) const
+ {
+ for (Index i = m_count - 1; i >= 0; i--)
{
- if (&rhs == this)
- {
- return true;
- }
- const Count count = getCount();
- if (count != rhs.getCount())
- {
- return false;
- }
- const T* thisEle = getBuffer();
- const T* rhsEle = rhs.getBuffer();
- for (Index i = 0; i < count; ++i)
- {
- if (thisEle[i] != rhsEle[i])
- {
- return false;
- }
- }
- return true;
+ if (m_buffer[i] == val)
+ return i;
}
- SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
+ return -1;
+ }
- ThisType head(Index index) const
+ template<typename Func>
+ Index findFirstIndex(const Func& predicate) const
+ {
+ for (Index i = 0; i < m_count; i++)
{
- SLANG_ASSERT(index >= 0 && index <= m_count);
- return ThisType(m_buffer, index);
+ if (predicate(m_buffer[i]))
+ return i;
}
- ThisType tail(Index index) const
+ return -1;
+ }
+
+ template<typename Func>
+ Index findLastIndex(const Func& predicate) const
+ {
+ for (Index i = m_count - 1; i >= 0; i--)
{
- SLANG_ASSERT(index >= 0 && index <= m_count);
- return ThisType(m_buffer + index, m_count - index);
+ if (predicate(m_buffer[i]))
+ return i;
}
+ return -1;
+ }
- ConstArrayView() :
- m_buffer(nullptr),
- m_count(0)
+ bool containsMemory(const ThisType& rhs) const
+ {
+ return rhs.getBuffer() >= getBuffer() && rhs.end() <= end();
+ }
+
+ bool operator==(const ThisType& rhs) const
+ {
+ if (&rhs == this)
{
+ return true;
}
-
- ConstArrayView(const T* buffer, Count count) :
- m_buffer(const_cast<T*>(buffer)),
- m_count(count)
+ const Count count = getCount();
+ if (count != rhs.getCount())
{
+ return false;
}
-
- protected:
- ConstArrayView(T* buffer, Count count) :
- m_buffer(buffer),
- m_count(count)
+ const T* thisEle = getBuffer();
+ const T* rhsEle = rhs.getBuffer();
+ for (Index i = 0; i < count; ++i)
{
+ if (thisEle[i] != rhsEle[i])
+ {
+ return false;
+ }
}
+ return true;
+ }
+ SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
- T* m_buffer; ///< Note that this isn't const, as is used for derived class ArrayView also
- Count m_count;
- };
+ ThisType head(Index index) const
+ {
+ SLANG_ASSERT(index >= 0 && index <= m_count);
+ return ThisType(m_buffer, index);
+ }
+ ThisType tail(Index index) const
+ {
+ SLANG_ASSERT(index >= 0 && index <= m_count);
+ return ThisType(m_buffer + index, m_count - index);
+ }
- template<typename T>
- ConstArrayView<T> makeConstArrayViewSingle(const T& obj)
+ ConstArrayView()
+ : m_buffer(nullptr), m_count(0)
{
- return ConstArrayView<T>(&obj, 1);
- }
+ }
- template<typename T>
- ConstArrayView<T> makeConstArrayView(const T* buffer, Count count)
+ ConstArrayView(const T* buffer, Count count)
+ : m_buffer(const_cast<T*>(buffer)), m_count(count)
{
- return ConstArrayView<T>(buffer, count);
}
- template<typename T, size_t N>
- ConstArrayView<T> makeConstArrayView(const T (&arr)[N])
+protected:
+ ConstArrayView(T* buffer, Count count)
+ : m_buffer(buffer), m_count(count)
{
- return ConstArrayView<T>(arr, Index(N));
}
+ T* m_buffer; ///< Note that this isn't const, as is used for derived class ArrayView also
+ Count m_count;
+};
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArrayView !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+template<typename T>
+ConstArrayView<T> makeConstArrayViewSingle(const T& obj)
+{
+ return ConstArrayView<T>(&obj, 1);
+}
- template<typename T>
- class ArrayView: public ConstArrayView<T>
- {
- public:
- typedef ArrayView ThisType;
+template<typename T>
+ConstArrayView<T> makeConstArrayView(const T* buffer, Count count)
+{
+ return ConstArrayView<T>(buffer, count);
+}
- typedef ConstArrayView<T> Super;
-
- using Super::m_buffer;
- using Super::m_count;
+template<typename T, size_t N>
+ConstArrayView<T> makeConstArrayView(const T (&arr)[N])
+{
+ return ConstArrayView<T>(arr, Index(N));
+}
- using Super::begin;
- T* begin() { return m_buffer; }
- using Super::end;
- T* end() { return m_buffer + m_count; }
-
- using Super::head;
- using Super::tail;
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArrayView !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- using Super::operator[];
- inline T& operator [](Index idx)
- {
- SLANG_ASSERT(idx >= 0 && idx < m_count);
- return m_buffer[idx];
- }
+template<typename T>
+class ArrayView : public ConstArrayView<T>
+{
+public:
+ typedef ArrayView ThisType;
- using Super::getBuffer;
- inline T* getBuffer() { return m_buffer; }
+ typedef ConstArrayView<T> Super;
- ThisType head(Index index)
- {
- SLANG_ASSERT(index >= 0 && index <= m_count);
- return ThisType(m_buffer, index);
- }
- ThisType tail(Index index)
- {
- SLANG_ASSERT(index >= 0 && index <= m_count);
- return ThisType(m_buffer + index, m_count - index);
- }
+ using Super::m_buffer;
+ using Super::m_count;
+
+ using Super::begin;
+ T* begin() { return m_buffer; }
- T& getLast() { return m_buffer[m_count - 1]; }
+ using Super::end;
+ T* end() { return m_buffer + m_count; }
- ArrayView() : Super() {}
- ArrayView(T* buffer, Index size) :Super(buffer, size) {}
- };
+ using Super::head;
+ using Super::tail;
- template<typename T>
- ArrayView<T> makeArrayViewSingle(T& obj)
+ using Super::operator[];
+ inline T& operator[](Index idx)
{
- return ArrayView<T>(&obj, 1);
- }
-
- template<typename T>
- ArrayView<T> makeArrayView(T* buffer, Count count)
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
+ return m_buffer[idx];
+ }
+
+ using Super::getBuffer;
+ inline T* getBuffer() { return m_buffer; }
+
+ ThisType head(Index index)
{
- return ArrayView<T>(buffer, count);
+ SLANG_ASSERT(index >= 0 && index <= m_count);
+ return ThisType(m_buffer, index);
}
+ ThisType tail(Index index)
+ {
+ SLANG_ASSERT(index >= 0 && index <= m_count);
+ return ThisType(m_buffer + index, m_count - index);
+ }
+
+ T& getLast() { return m_buffer[m_count - 1]; }
- template<typename T, size_t N>
- ArrayView<T> makeArrayView(T (&arr)[N])
+ ArrayView()
+ : Super()
{
- return ArrayView<T>(arr, Count(N));
}
+ ArrayView(T* buffer, Index size)
+ : Super(buffer, size)
+ {
+ }
+};
+
+template<typename T>
+ArrayView<T> makeArrayViewSingle(T& obj)
+{
+ return ArrayView<T>(&obj, 1);
+}
+template<typename T>
+ArrayView<T> makeArrayView(T* buffer, Count count)
+{
+ return ArrayView<T>(buffer, count);
+}
+template<typename T, size_t N>
+ArrayView<T> makeArrayView(T (&arr)[N])
+{
+ return ArrayView<T>(arr, Count(N));
}
+
+} // namespace Slang
+
#endif
diff --git a/source/core/slang-array.h b/source/core/slang-array.h
index d24ff0970..5c2fefc26 100644
--- a/source/core/slang-array.h
+++ b/source/core/slang-array.h
@@ -1,197 +1,220 @@
#ifndef SLANG_CORE_ARRAY_H
#define SLANG_CORE_ARRAY_H
-#include "slang-exception.h"
#include "slang-array-view.h"
+#include "slang-exception.h"
namespace Slang
{
- /* An array container with fixed maximum size defined by COUNT. */
- template<typename T, Index COUNT>
- class Array
- {
- public:
- T* begin() { return m_buffer; }
- const T* begin() const { return m_buffer; }
-
- const T* end() const { return m_buffer + m_count; }
- T* end() { return m_buffer + m_count; }
-
- inline Index getCapacity() const { return COUNT; }
- inline Index getCount() const { return m_count; }
- inline const T& getFirst() const
- {
- SLANG_ASSERT(m_count > 0);
- return m_buffer[0];
- }
- inline T& getFirst()
- {
- SLANG_ASSERT(m_count > 0);
- return m_buffer[0];
- }
- inline const T& getLast() const
- {
- SLANG_ASSERT(m_count > 0);
- return m_buffer[m_count - 1];
- }
- inline T& getLast()
- {
- SLANG_ASSERT(m_count > 0);
- return m_buffer[m_count - 1];
- }
- inline void setCount(Index newCount)
- {
- SLANG_ASSERT(newCount >= 0 && newCount <= COUNT);
- m_count = newCount;
- }
- inline void add(const T& item)
- {
- SLANG_ASSERT(m_count < COUNT);
- m_buffer[m_count++] = item;
- }
- inline void add(T&& item)
- {
- SLANG_ASSERT(m_count < COUNT);
- m_buffer[m_count++] = _Move(item);
- }
-
- inline const T& operator [](Index idx) const
- {
- SLANG_ASSERT(idx >= 0 && idx < m_count);
- return m_buffer[idx];
- }
- inline T& operator [](Index idx)
- {
- SLANG_ASSERT(idx >= 0 && idx < m_count);
- return m_buffer[idx];
- }
-
- inline const T* getBuffer() const { return m_buffer; }
- inline T* getBuffer() { return m_buffer; }
-
- inline void clear() { m_count = 0; }
-
- template<typename T2>
- Index indexOf(const T2& val) const { return getView().indexOf(val); }
- template<typename T2>
- Index lastIndexOf(const T2& val) const { return getView().lastIndexOf(val); }
- template<typename Func>
- Index findFirstIndex(const Func& predicate) const { return getView().findFirstIndex(predicate); }
- template<typename Func>
- Index findLastIndex(const Func& predicate) const { return getView().findLastIndex(predicate); }
-
- inline ConstArrayView<T> getView() const { return ConstArrayView<T>(m_buffer, m_count); }
- inline ConstArrayView<T> getView(Index start, Index count) const
- {
- SLANG_ASSERT(start >= 0 && count >= 0);
- SLANG_ASSERT(start <= m_count && start + count < m_count);
- return ConstArrayView<T>(m_buffer + start, count);
- }
-
- inline ArrayView<T> getView() { return ArrayView<T>(m_buffer, m_count); }
- inline ArrayView<T> getView(Index start, Index count)
- {
- SLANG_ASSERT(start >= 0 && count >= 0);
- SLANG_ASSERT(start <= m_count && start + count < m_count);
- return ArrayView<T>(m_buffer + start, count);
- }
-
- private:
- T m_buffer[COUNT];
- Index m_count = 0;
- };
-
- template<typename T>
- class Array<T, 0>
- {
- public:
- T* begin() { return nullptr; }
- const T* begin() const { return nullptr; }
-
- const T* end() const { return nullptr; }
- T* end() { return nullptr; }
-
- inline Index getCapacity() const { return 0; }
- inline Index getCount() const { return 0; }
- inline void setCount(Index newCount)
- {
- SLANG_ASSERT(newCount == 0);
- }
- inline const T* getBuffer() const { return nullptr; }
- inline T* getBuffer() { return nullptr; }
- inline void clear() {}
-
- template<typename T2>
- Index indexOf(const T2& val) const { return getView().indexOf(val); }
- template<typename T2>
- Index lastIndexOf(const T2& val) const { return getView().lastIndexOf(val); }
- template<typename Func>
- Index findFirstIndex(const Func& predicate) const { return getView().findFirstIndex(predicate); }
- template<typename Func>
- Index findLastIndex(const Func& predicate) const { return getView().findLastIndex(predicate); }
-
- inline ConstArrayView<T> getView() const { return ConstArrayView<T>(nullptr, 0); }
- inline ConstArrayView<T> getView(Index start, Index count) const
- {
- SLANG_ASSERT(start == 0 && count == 0);
- return ConstArrayView<T>(nullptr, 0);
- }
-
- inline ArrayView<T> getView() { return ArrayView<T>(nullptr, 0); }
- inline ArrayView<T> getView(Index start, Index count)
- {
- SLANG_ASSERT(start == 0 && count == 0);
- return ArrayView<T>(nullptr, 0);
- }
- };
-
- template<typename T, typename ...TArgs>
- struct FirstType
- {
- typedef T Type;
- };
-
-
- template<typename T, Index SIZE>
- void insertArray(Array<T, SIZE>&) {}
-
- template<typename T, typename ...TArgs, Index SIZE>
- void insertArray(Array<T, SIZE>& arr, const T& val, TArgs... args)
- {
- arr.add(val);
- insertArray<T>(arr, args...);
- }
-
- template<typename ...TArgs>
- auto makeArray(TArgs ...args) -> Array<typename FirstType<TArgs...>::Type, sizeof...(args)>
- {
- Array<typename FirstType<TArgs...>::Type, Index(sizeof...(args))> rs;
- insertArray<typename FirstType<TArgs...>::Type>(rs, args...);
- return rs;
- }
-
- template<typename T>
- auto makeArray() -> Array<T, 0>
- {
- return Array<T, 0>();
- }
-
-
- template<typename TList>
- void addToList(TList&)
- {
- }
- template<typename TList, typename T>
- void addToList(TList& list, T node)
- {
- list.add(node);
- }
- template<typename TList, typename T, typename ... TArgs>
- void addToList(TList& list, T node, TArgs ... args)
- {
- list.add(node);
- addToList(list, args...);
+/* An array container with fixed maximum size defined by COUNT. */
+template<typename T, Index COUNT>
+class Array
+{
+public:
+ T* begin() { return m_buffer; }
+ const T* begin() const { return m_buffer; }
+
+ const T* end() const { return m_buffer + m_count; }
+ T* end() { return m_buffer + m_count; }
+
+ inline Index getCapacity() const { return COUNT; }
+ inline Index getCount() const { return m_count; }
+ inline const T& getFirst() const
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_buffer[0];
+ }
+ inline T& getFirst()
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_buffer[0];
+ }
+ inline const T& getLast() const
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_buffer[m_count - 1];
+ }
+ inline T& getLast()
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_buffer[m_count - 1];
+ }
+ inline void setCount(Index newCount)
+ {
+ SLANG_ASSERT(newCount >= 0 && newCount <= COUNT);
+ m_count = newCount;
+ }
+ inline void add(const T& item)
+ {
+ SLANG_ASSERT(m_count < COUNT);
+ m_buffer[m_count++] = item;
+ }
+ inline void add(T&& item)
+ {
+ SLANG_ASSERT(m_count < COUNT);
+ m_buffer[m_count++] = _Move(item);
+ }
+
+ inline const T& operator[](Index idx) const
+ {
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
+ return m_buffer[idx];
+ }
+ inline T& operator[](Index idx)
+ {
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
+ return m_buffer[idx];
+ }
+
+ inline const T* getBuffer() const { return m_buffer; }
+ inline T* getBuffer() { return m_buffer; }
+
+ inline void clear() { m_count = 0; }
+
+ template<typename T2>
+ Index indexOf(const T2& val) const
+ {
+ return getView().indexOf(val);
+ }
+ template<typename T2>
+ Index lastIndexOf(const T2& val) const
+ {
+ return getView().lastIndexOf(val);
+ }
+ template<typename Func>
+ Index findFirstIndex(const Func& predicate) const
+ {
+ return getView().findFirstIndex(predicate);
+ }
+ template<typename Func>
+ Index findLastIndex(const Func& predicate) const
+ {
+ return getView().findLastIndex(predicate);
+ }
+
+ inline ConstArrayView<T> getView() const { return ConstArrayView<T>(m_buffer, m_count); }
+ inline ConstArrayView<T> getView(Index start, Index count) const
+ {
+ SLANG_ASSERT(start >= 0 && count >= 0);
+ SLANG_ASSERT(start <= m_count && start + count < m_count);
+ return ConstArrayView<T>(m_buffer + start, count);
+ }
+
+ inline ArrayView<T> getView() { return ArrayView<T>(m_buffer, m_count); }
+ inline ArrayView<T> getView(Index start, Index count)
+ {
+ SLANG_ASSERT(start >= 0 && count >= 0);
+ SLANG_ASSERT(start <= m_count && start + count < m_count);
+ return ArrayView<T>(m_buffer + start, count);
}
+
+private:
+ T m_buffer[COUNT];
+ Index m_count = 0;
+};
+
+template<typename T>
+class Array<T, 0>
+{
+public:
+ T* begin() { return nullptr; }
+ const T* begin() const { return nullptr; }
+
+ const T* end() const { return nullptr; }
+ T* end() { return nullptr; }
+
+ inline Index getCapacity() const { return 0; }
+ inline Index getCount() const { return 0; }
+ inline void setCount(Index newCount) { SLANG_ASSERT(newCount == 0); }
+ inline const T* getBuffer() const { return nullptr; }
+ inline T* getBuffer() { return nullptr; }
+ inline void clear() {}
+
+ template<typename T2>
+ Index indexOf(const T2& val) const
+ {
+ return getView().indexOf(val);
+ }
+ template<typename T2>
+ Index lastIndexOf(const T2& val) const
+ {
+ return getView().lastIndexOf(val);
+ }
+ template<typename Func>
+ Index findFirstIndex(const Func& predicate) const
+ {
+ return getView().findFirstIndex(predicate);
+ }
+ template<typename Func>
+ Index findLastIndex(const Func& predicate) const
+ {
+ return getView().findLastIndex(predicate);
+ }
+
+ inline ConstArrayView<T> getView() const { return ConstArrayView<T>(nullptr, 0); }
+ inline ConstArrayView<T> getView(Index start, Index count) const
+ {
+ SLANG_ASSERT(start == 0 && count == 0);
+ return ConstArrayView<T>(nullptr, 0);
+ }
+
+ inline ArrayView<T> getView() { return ArrayView<T>(nullptr, 0); }
+ inline ArrayView<T> getView(Index start, Index count)
+ {
+ SLANG_ASSERT(start == 0 && count == 0);
+ return ArrayView<T>(nullptr, 0);
+ }
+};
+
+template<typename T, typename... TArgs>
+struct FirstType
+{
+ typedef T Type;
+};
+
+
+template<typename T, Index SIZE>
+void insertArray(Array<T, SIZE>&)
+{
+}
+
+template<typename T, typename... TArgs, Index SIZE>
+void insertArray(Array<T, SIZE>& arr, const T& val, TArgs... args)
+{
+ arr.add(val);
+ insertArray<T>(arr, args...);
+}
+
+template<typename... TArgs>
+auto makeArray(TArgs... args) -> Array<typename FirstType<TArgs...>::Type, sizeof...(args)>
+{
+ Array<typename FirstType<TArgs...>::Type, Index(sizeof...(args))> rs;
+ insertArray<typename FirstType<TArgs...>::Type>(rs, args...);
+ return rs;
+}
+
+template<typename T>
+auto makeArray() -> Array<T, 0>
+{
+ return Array<T, 0>();
+}
+
+
+template<typename TList>
+void addToList(TList&)
+{
+}
+template<typename TList, typename T>
+void addToList(TList& list, T node)
+{
+ list.add(node);
+}
+template<typename TList, typename T, typename... TArgs>
+void addToList(TList& list, T node, TArgs... args)
+{
+ list.add(node);
+ addToList(list, args...);
}
+} // namespace Slang
#endif
diff --git a/source/core/slang-basic.h b/source/core/slang-basic.h
index 5387af4aa..d37782160 100644
--- a/source/core/slang-basic.h
+++ b/source/core/slang-basic.h
@@ -1,14 +1,14 @@
#ifndef SLANG_CORE_BASIC_H
#define SLANG_CORE_BASIC_H
-#include "slang-common.h"
-#include "slang-math.h"
-#include "slang-string.h"
#include "slang-array.h"
+#include "slang-common.h"
+#include "slang-dictionary.h"
+#include "slang-exception.h"
#include "slang-list.h"
+#include "slang-math.h"
#include "slang-short-list.h"
#include "slang-smart-pointer.h"
-#include "slang-exception.h"
-#include "slang-dictionary.h"
+#include "slang-string.h"
#endif
diff --git a/source/core/slang-blob.cpp b/source/core/slang-blob.cpp
index 19a4281bd..ea4f4b6c0 100644
--- a/source/core/slang-blob.cpp
+++ b/source/core/slang-blob.cpp
@@ -1,13 +1,13 @@
#include "slang-blob.h"
-namespace Slang {
+namespace Slang
+{
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BlobBase !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
ISlangUnknown* BlobBase::getInterface(const Guid& guid)
{
- if (guid == ISlangUnknown::getTypeGuid() ||
- guid == ISlangBlob::getTypeGuid())
+ if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangBlob::getTypeGuid())
{
return static_cast<ISlangBlob*>(this);
}
@@ -41,12 +41,11 @@ void StringBlob::_setUniqueRep(StringRepresentation* uniqueRep)
m_uniqueRep = uniqueRep;
- m_slice = uniqueRep ?
- UnownedTerminatedStringSlice(uniqueRep->getData(), uniqueRep->getLength()) :
- UnownedTerminatedStringSlice();
+ m_slice = uniqueRep ? UnownedTerminatedStringSlice(uniqueRep->getData(), uniqueRep->getLength())
+ : UnownedTerminatedStringSlice();
}
-/* static */StringRepresentation* StringBlob::_createUniqueCopy(StringRepresentation* rep)
+/* static */ StringRepresentation* StringBlob::_createUniqueCopy(StringRepresentation* rep)
{
if (rep)
{
@@ -75,7 +74,7 @@ void StringBlob::_setWithMove(StringRepresentation* rep)
if (rep && !rep->isUniquelyReferenced())
{
_setUniqueRep(_createUniqueCopy(rep));
- // We need to release a ref as rep is passed in with the 'current' ref count
+ // We need to release a ref as rep is passed in with the 'current' ref count
rep->releaseReference();
}
else
@@ -84,7 +83,7 @@ void StringBlob::_setWithMove(StringRepresentation* rep)
}
}
-/* static */ComPtr<ISlangBlob> StringBlob::create(const UnownedStringSlice& slice)
+/* static */ ComPtr<ISlangBlob> StringBlob::create(const UnownedStringSlice& slice)
{
StringRepresentation* rep = nullptr;
if (slice.getLength())
@@ -93,27 +92,27 @@ void StringBlob::_setWithMove(StringRepresentation* rep)
}
auto blob = new StringBlob;
-
+
// rep must be unique at this point
blob->_setUniqueRep(rep);
return ComPtr<ISlangBlob>(blob);
}
-/* static */ComPtr<ISlangBlob> StringBlob::create(const String& in)
+/* static */ ComPtr<ISlangBlob> StringBlob::create(const String& in)
{
auto blob = new StringBlob;
blob->_setWithCopy(in.getStringRepresentation());
return ComPtr<ISlangBlob>(blob);
}
-/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String& in)
+/* static */ ComPtr<ISlangBlob> StringBlob::moveCreate(String& in)
{
auto blob = new StringBlob;
blob->_setWithMove(in.detachStringRepresentation());
return ComPtr<ISlangBlob>(blob);
}
-/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String&& in)
+/* static */ ComPtr<ISlangBlob> StringBlob::moveCreate(String&& in)
{
auto blob = new StringBlob;
blob->_setWithMove(in.detachStringRepresentation());
@@ -167,7 +166,7 @@ void* RawBlob::getObject(const Guid& guid)
// If the data has 0 termination, we can return the pointer
if (guid == SlangTerminatedChars::getTypeGuid() && m_data.isTerminated())
{
- return (char*)m_data.getData();
+ return (char*)m_data.getData();
}
return nullptr;
}
@@ -185,7 +184,7 @@ void* ScopeBlob::castAs(const SlangUUID& guid)
return obj;
}
- // If the contained thing is castable, ask it
+ // If the contained thing is castable, ask it
if (m_castable)
{
return m_castable->castAs(guid);
@@ -225,7 +224,7 @@ void* ListBlob::getObject(const Guid& guid)
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StaticBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-SlangResult StaticBlob::queryInterface(SlangUUID const& guid, void** outObject)
+SlangResult StaticBlob::queryInterface(SlangUUID const& guid, void** outObject)
{
if (auto intf = getInterface(guid))
{
@@ -246,8 +245,7 @@ void* StaticBlob::castAs(const SlangUUID& guid)
ISlangUnknown* StaticBlob::getInterface(const Guid& guid)
{
- if (guid == ISlangUnknown::getTypeGuid() ||
- guid == ISlangBlob::getTypeGuid())
+ if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangBlob::getTypeGuid())
{
return static_cast<ISlangBlob*>(this);
}
diff --git a/source/core/slang-blob.h b/source/core/slang-blob.h
index 4df8f0db6..af3206fb5 100644
--- a/source/core/slang-blob.h
+++ b/source/core/slang-blob.h
@@ -1,22 +1,20 @@
#ifndef SLANG_CORE_BLOB_H
#define SLANG_CORE_BLOB_H
-#include "slang.h"
-
-#include "slang-string.h"
-#include "slang-list.h"
-
-#include <stdarg.h>
-
+#include "../core/slang-com-object.h"
#include "slang-com-helper.h"
#include "slang-com-ptr.h"
+#include "slang-list.h"
+#include "slang-string.h"
+#include "slang.h"
-#include "../core/slang-com-object.h"
+#include <stdarg.h>
-namespace Slang {
+namespace Slang
+{
/** Base class for simple blobs.
-*/
+ */
class BlobBase : public ISlangBlob, public ICastable, public ComBaseObject
{
public:
@@ -33,53 +31,57 @@ protected:
/** A blob that uses a `StringRepresentation` for its storage.
-By design the StringBlob owns a unique reference to the StringRepresentation.
+By design the StringBlob owns a unique reference to the StringRepresentation.
This is because StringBlob, implements an interface which should work across threads.
*/
class StringBlob : public BlobBase
{
public:
- SLANG_CLASS_GUID(0xf7e0e93c, 0xde70, 0x4531, { 0x9c, 0x9f, 0xdd, 0xa3, 0xf6, 0xc6, 0xc0, 0xdd });
+ SLANG_CLASS_GUID(0xf7e0e93c, 0xde70, 0x4531, {0x9c, 0x9f, 0xdd, 0xa3, 0xf6, 0xc6, 0xc0, 0xdd});
// ICastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
// ISlangBlob
- SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_slice.begin(); }
+ SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE
+ {
+ return m_slice.begin();
+ }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_slice.getLength(); }
- /// Since in is not being moved will *always* create a new representation, unless the in is empty
+ /// Since in is not being moved will *always* create a new representation, unless the in is
+ /// empty
static ComPtr<ISlangBlob> create(const String& in);
- /// Create from a slice
+ /// Create from a slice
static ComPtr<ISlangBlob> create(const UnownedStringSlice& slice);
- /// Moves from in into the created blob.
- /// NOTE! That will only use the representation from in, if it is *unique*
- /// otherwise it will make a new copy.
+ /// Moves from in into the created blob.
+ /// NOTE! That will only use the representation from in, if it is *unique*
+ /// otherwise it will make a new copy.
static ComPtr<ISlangBlob> moveCreate(String& in);
static ComPtr<ISlangBlob> moveCreate(String&& in);
- /// Dtor
+ /// Dtor
~StringBlob();
protected:
-
- /// Init with a rep when can't be owned.
+ /// Init with a rep when can't be owned.
void _setWithCopy(StringRepresentation* rep);
- /// Init with a representation that has been moved.
+ /// Init with a representation that has been moved.
void _setWithMove(StringRepresentation* rep);
- /// Create a unique copy of rep.
- /// If nullptr will work (if rep is empty, will return that)
+ /// Create a unique copy of rep.
+ /// If nullptr will work (if rep is empty, will return that)
static StringRepresentation* _createUniqueCopy(StringRepresentation* rep);
- /// Rep can only be nullptr or have a single ref
+ /// Rep can only be nullptr or have a single ref
void _setUniqueRep(StringRepresentation* rep);
void* getObject(const Guid& guid);
- UnownedTerminatedStringSlice m_slice; ///< The contents
- StringRepresentation* m_uniqueRep = nullptr; ///< Holds actual bytes. Can be nullptr if it's an empty string.
+ UnownedTerminatedStringSlice m_slice; ///< The contents
+ StringRepresentation* m_uniqueRep =
+ nullptr; ///< Holds actual bytes. Can be nullptr if it's an empty string.
};
class ListBlob : public BlobBase
@@ -91,17 +93,32 @@ public:
// ICastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
// ISlangBlob
- SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data.getBuffer(); }
+ SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE
+ {
+ return m_data.getBuffer();
+ }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_data.getCount(); }
- static ComPtr<ISlangBlob> create(const List<uint8_t>& data) { return ComPtr<ISlangBlob>(new ListBlob(data)); }
-
- static ComPtr<ISlangBlob> moveCreate(List<uint8_t>& data) { return ComPtr<ISlangBlob>(new ListBlob(_Move(data))); }
+ static ComPtr<ISlangBlob> create(const List<uint8_t>& data)
+ {
+ return ComPtr<ISlangBlob>(new ListBlob(data));
+ }
+
+ static ComPtr<ISlangBlob> moveCreate(List<uint8_t>& data)
+ {
+ return ComPtr<ISlangBlob>(new ListBlob(_Move(data)));
+ }
protected:
- explicit ListBlob(const List<uint8_t>& data) : m_data(data) {}
- // Move ctor
- explicit ListBlob(List<uint8_t>&& data) : m_data(data) {}
+ explicit ListBlob(const List<uint8_t>& data)
+ : m_data(data)
+ {
+ }
+ // Move ctor
+ explicit ListBlob(List<uint8_t>&& data)
+ : m_data(data)
+ {
+ }
void* getObject(const Guid& guid);
@@ -126,7 +143,7 @@ public:
m_capacityInBytes = size;
return m_data;
}
- /// Allocate size including a 0 byte at `size`.
+ /// Allocate size including a 0 byte at `size`.
void* allocateTerminated(size_t size)
{
SLANG_ASSUME(size != std::numeric_limits<size_t>::max());
@@ -146,7 +163,8 @@ public:
m_sizeInBytes = 0;
m_capacityInBytes = 0;
}
- // Reallocate so the buffer is the specified capacity/size. Contents of buffer up to size remain intact.
+ // Reallocate so the buffer is the specified capacity/size. Contents of buffer up to size remain
+ // intact.
void reallocate(size_t capacity)
{
if (capacity != m_capacityInBytes)
@@ -156,7 +174,8 @@ public:
m_capacityInBytes = capacity;
}
}
- /// Makes this no longer own the allocation. Returns the allocated data (or nullptr if no allocation)
+ /// Makes this no longer own the allocation. Returns the allocated data (or nullptr if no
+ /// allocation)
void* detach()
{
void* data = m_data;
@@ -185,14 +204,14 @@ public:
return dst;
}
- /// Get the allocated data. Returns nullptr if there is no allocated data
+ /// Get the allocated data. Returns nullptr if there is no allocated data
void* getData() const { return m_data; }
- /// Get the size of the allocated data.
+ /// Get the size of the allocated data.
size_t getSizeInBytes() const { return m_sizeInBytes; }
- /// Get the capacity in bytes
+ /// Get the capacity in bytes
size_t getCapacityInBytes() const { return m_capacityInBytes; }
- void setSizeInBytes(size_t size)
+ void setSizeInBytes(size_t size)
{
SLANG_ASSERT(size <= m_capacityInBytes);
m_sizeInBytes = size;
@@ -205,13 +224,14 @@ public:
Swap(m_capacityInBytes, rhs.m_capacityInBytes);
}
- /// True if has zero termination, at the byte at m_sizeInBytes
- bool isTerminated() const { return m_capacityInBytes > m_sizeInBytes && ((const char*)m_data)[m_sizeInBytes] == 0; }
+ /// True if has zero termination, at the byte at m_sizeInBytes
+ bool isTerminated() const
+ {
+ return m_capacityInBytes > m_sizeInBytes && ((const char*)m_data)[m_sizeInBytes] == 0;
+ }
- ScopedAllocation() :
- m_data(nullptr),
- m_sizeInBytes(0),
- m_capacityInBytes(0)
+ ScopedAllocation()
+ : m_data(nullptr), m_sizeInBytes(0), m_capacityInBytes(0)
{
}
@@ -228,15 +248,21 @@ private:
};
/** A blob that manages some raw data that it owns.
-*/
+ */
class RawBlob : public BlobBase
{
public:
// ICastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
// ISlangBlob
- SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data.getData(); }
- SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_data.getSizeInBytes(); }
+ SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE
+ {
+ return m_data.getData();
+ }
+ SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE
+ {
+ return m_data.getSizeInBytes();
+ }
static ComPtr<ISlangBlob> moveCreate(ScopedAllocation& alloc)
{
@@ -245,7 +271,7 @@ public:
return ComPtr<ISlangBlob>(blob);
}
- /// Create a blob that will retain (a copy of) raw data.
+ /// Create a blob that will retain (a copy of) raw data.
static inline ComPtr<ISlangBlob> create(void const* inData, size_t size)
{
return ComPtr<ISlangBlob>(new RawBlob(inData, size));
@@ -254,10 +280,7 @@ public:
protected:
// Ctor
// NOTE! Takes a copy of the input data
- RawBlob(const void* data, size_t size)
- {
- memcpy(m_data.allocateTerminated(size), data, size);
- }
+ RawBlob(const void* data, size_t size) { memcpy(m_data.allocateTerminated(size), data, size); }
void* getObject(const Guid& guid);
@@ -281,9 +304,8 @@ public:
protected:
// Ctor
- UnownedRawBlob(const void* data, size_t size) :
- m_data(data),
- m_dataSizeInBytes(size)
+ UnownedRawBlob(const void* data, size_t size)
+ : m_data(data), m_dataSizeInBytes(size)
{
}
@@ -300,9 +322,9 @@ This is useful when a Blob is useful to represent some global immutable chunk of
class StaticBlob : public ISlangBlob, public ICastable
{
public:
-
// ISlangUnknown
- SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject)
+ SLANG_OVERRIDE;
SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
@@ -313,9 +335,8 @@ public:
SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data; }
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_dataCount; }
- StaticBlob(const void* data, size_t dataCount):
- m_data(data),
- m_dataCount(dataCount)
+ StaticBlob(const void* data, size_t dataCount)
+ : m_data(data), m_dataCount(dataCount)
{
}
@@ -334,8 +355,14 @@ public:
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
// ISlangBlob
- SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_blob->getBufferPointer(); }
- SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_blob->getBufferSize(); }
+ SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE
+ {
+ return m_blob->getBufferPointer();
+ }
+ SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE
+ {
+ return m_blob->getBufferSize();
+ }
static inline ComPtr<ISlangBlob> create(ISlangBlob* blob, ISlangUnknown* scope)
{
@@ -343,11 +370,9 @@ public:
}
protected:
-
// Ctor
- ScopeBlob(ISlangBlob* blob, ISlangUnknown* scope) :
- m_blob(blob),
- m_scope(scope)
+ ScopeBlob(ISlangBlob* blob, ISlangUnknown* scope)
+ : m_blob(blob), m_scope(scope)
{
// Cache the ICastable interface if there is one.
blob->queryInterface(SLANG_IID_PPV_ARGS(m_castable.writeRef()));
@@ -355,7 +380,8 @@ protected:
ComPtr<ISlangUnknown> m_scope;
ComPtr<ISlangBlob> m_blob;
- ComPtr<ICastable> m_castable; ///< Set if the blob has this interface. Set to nullptr if does not.
+ ComPtr<ICastable>
+ m_castable; ///< Set if the blob has this interface. Set to nullptr if does not.
};
} // namespace Slang
diff --git a/source/core/slang-byte-encode-util.cpp b/source/core/slang-byte-encode-util.cpp
index c7022397f..acafdf2b4 100644
--- a/source/core/slang-byte-encode-util.cpp
+++ b/source/core/slang-byte-encode-util.cpp
@@ -1,17 +1,18 @@
#include "slang-byte-encode-util.h"
-namespace Slang {
+namespace Slang
+{
// Descriptions of algorithms here...
// https://github.com/stoklund/varint
#if SLANG_LITTLE_ENDIAN && SLANG_UNALIGNED_ACCESS
// Testing on i7, unaligned access is around 40% faster
-# define SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS 1
+#define SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS 1
#endif
#ifndef SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS
-# define SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS 0
+#define SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS 0
#endif
#define SLANG_REPEAT_2(n) n, n
@@ -22,23 +23,22 @@ namespace Slang {
#define SLANG_REPEAT_64(n) SLANG_REPEAT_32(n), SLANG_REPEAT_32(n)
#define SLANG_REPEAT_128(n) SLANG_REPEAT_64(n), SLANG_REPEAT_64(n)
-/* static */const int8_t ByteEncodeUtil::s_msb8[256] =
-{
- - 1,
- 0,
- SLANG_REPEAT_2(1),
- SLANG_REPEAT_4(2),
- SLANG_REPEAT_8(3),
- SLANG_REPEAT_16(4),
+/* static */ const int8_t ByteEncodeUtil::s_msb8[256] = {
+ -1,
+ 0,
+ SLANG_REPEAT_2(1),
+ SLANG_REPEAT_4(2),
+ SLANG_REPEAT_8(3),
+ SLANG_REPEAT_16(4),
SLANG_REPEAT_32(5),
SLANG_REPEAT_64(6),
SLANG_REPEAT_128(7),
};
-/* static */size_t ByteEncodeUtil::calcEncodeLiteSizeUInt32(const uint32_t* in, size_t num)
+/* static */ size_t ByteEncodeUtil::calcEncodeLiteSizeUInt32(const uint32_t* in, size_t num)
{
size_t totalNumEncodeBytes = 0;
-
+
for (size_t i = 0; i < num; i++)
{
const uint32_t v = in[i];
@@ -59,7 +59,10 @@ namespace Slang {
return totalNumEncodeBytes;
}
-/* static */size_t ByteEncodeUtil::encodeLiteUInt32(const uint32_t* in, size_t num, uint8_t* encodeOut)
+/* static */ size_t ByteEncodeUtil::encodeLiteUInt32(
+ const uint32_t* in,
+ size_t num,
+ uint8_t* encodeOut)
{
uint8_t* encodeStart = encodeOut;
@@ -67,7 +70,7 @@ namespace Slang {
{
uint32_t v = in[i];
- if(v < kLiteCut1)
+ if (v < kLiteCut1)
{
*encodeOut++ = uint8_t(v);
}
@@ -95,7 +98,10 @@ namespace Slang {
return size_t(encodeOut - encodeStart);
}
-/* static */void ByteEncodeUtil::encodeLiteUInt32(const uint32_t* in, size_t num, List<uint8_t>& encodeArrayOut)
+/* static */ void ByteEncodeUtil::encodeLiteUInt32(
+ const uint32_t* in,
+ size_t num,
+ List<uint8_t>& encodeArrayOut)
{
// Make sure there is at least enough space for all bytes
encodeArrayOut.setCount(num);
@@ -111,7 +117,7 @@ namespace Slang {
const size_t offset = size_t(encodeOut - encodeArrayOut.begin());
const UInt oldCapacity = encodeArrayOut.getCapacity();
-
+
// Make some more space
encodeArrayOut.reserve(oldCapacity + (oldCapacity >> 1) + kMaxLiteEncodeUInt32);
// Make the size the capacity
@@ -154,7 +160,7 @@ namespace Slang {
encodeArrayOut.compress();
}
-/* static */int ByteEncodeUtil::encodeLiteUInt32(uint32_t in, uint8_t out[kMaxLiteEncodeUInt32])
+/* static */ int ByteEncodeUtil::encodeLiteUInt32(uint32_t in, uint8_t out[kMaxLiteEncodeUInt32])
{
// 0-184 1 byte value = B0
// 185 - 248 2 bytes value = 185 + 256 * (B0 - 185) + B1
@@ -187,8 +193,7 @@ namespace Slang {
}
}
-static const uint32_t s_unalignedUInt32Mask[5] =
-{
+static const uint32_t s_unalignedUInt32Mask[5] = {
0x00000000,
0x000000ff,
0x0000ffff,
@@ -196,8 +201,8 @@ static const uint32_t s_unalignedUInt32Mask[5] =
0xffffffff,
};
-// Decode the >= kLiteCut2.
-// in is pointing past the first byte.
+// Decode the >= kLiteCut2.
+// in is pointing past the first byte.
// Only valid numBytesRemaining is 2, 3, or 4
SLANG_FORCE_INLINE static uint32_t _decodeLiteCut2UInt32(const uint8_t* in, int numBytesRemaining)
{
@@ -205,26 +210,26 @@ SLANG_FORCE_INLINE static uint32_t _decodeLiteCut2UInt32(const uint8_t* in, int
#if SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS
switch (numBytesRemaining)
{
- case 2: value = *(const uint16_t*)in; break;
- case 3: value = (uint32_t(in[2]) << 16) | (uint32_t(in[1]) << 8) | uint32_t(in[0]); break;
- case 4: value = *(const uint32_t*)in; break;
- default: break;
+ case 2: value = *(const uint16_t*)in; break;
+ case 3: value = (uint32_t(in[2]) << 16) | (uint32_t(in[1]) << 8) | uint32_t(in[0]); break;
+ case 4: value = *(const uint32_t*)in; break;
+ default: break;
}
#else
// This works on all cpus although slower
value = in[0];
switch (numBytesRemaining)
{
- case 4: value |= uint32_t(in[3]) << 24; /* fall thru */
- case 3: value |= uint32_t(in[2]) << 16; /* fall thru */
- case 2: value |= uint32_t(in[1]) << 8; /* fall thru */
- case 1: break;
+ case 4: value |= uint32_t(in[3]) << 24; /* fall thru */
+ case 3: value |= uint32_t(in[2]) << 16; /* fall thru */
+ case 2: value |= uint32_t(in[1]) << 8; /* fall thru */
+ case 1: break;
}
#endif
return value;
}
-/* static */int ByteEncodeUtil::decodeLiteUInt32(const uint8_t* in, uint32_t* out)
+/* static */ int ByteEncodeUtil::decodeLiteUInt32(const uint8_t* in, uint32_t* out)
{
uint8_t b0 = *in++;
if (b0 < kLiteCut1)
@@ -246,7 +251,10 @@ SLANG_FORCE_INLINE static uint32_t _decodeLiteCut2UInt32(const uint8_t* in, int
}
}
-/* static */size_t ByteEncodeUtil::decodeLiteUInt32(const uint8_t* encodeIn, size_t numValues, uint32_t* valuesOut)
+/* static */ size_t ByteEncodeUtil::decodeLiteUInt32(
+ const uint8_t* encodeIn,
+ size_t numValues,
+ uint32_t* valuesOut)
{
const uint8_t* encodeStart = encodeIn;
@@ -267,13 +275,13 @@ SLANG_FORCE_INLINE static uint32_t _decodeLiteCut2UInt32(const uint8_t* in, int
const int numBytesRemaining = b0 - kLiteCut2 + 2 - 1;
// For unaligned access, do not use unaligned access for the last two values,
- // (3rd last is safe because this value will have at least 2 bytes, followed by at worst two 1-byte values)
- // otherwise we can access outside the bounds of the encoded array
+ // (3rd last is safe because this value will have at least 2 bytes, followed by at worst
+ // two 1-byte values) otherwise we can access outside the bounds of the encoded array
// This prevents memory validation tools from causing an exception here
if (SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS && i < numValues - 2)
{
const uint32_t mask = s_unalignedUInt32Mask[numBytesRemaining];
- //const uint32_t mask = ~(uint32_t(0xffffff00) << ((numBytesRemaining - 1) * 8));
+ // const uint32_t mask = ~(uint32_t(0xffffff00) << ((numBytesRemaining - 1) * 8));
valuesOut[i] = (*(const uint32_t*)encodeIn) & mask;
}
else
diff --git a/source/core/slang-byte-encode-util.h b/source/core/slang-byte-encode-util.h
index 728f9ac2f..81fc0ef98 100644
--- a/source/core/slang-byte-encode-util.h
+++ b/source/core/slang-byte-encode-util.h
@@ -3,88 +3,90 @@
#include "slang-list.h"
-namespace Slang {
+namespace Slang
+{
struct ByteEncodeUtil
{
enum
{
kMaxLiteEncodeUInt16 = 3, /// One byte for prefix, the remaining 2 bytes hold the value
- kMaxLiteEncodeUInt32 = 5, /// One byte for prefix, the remaining 4 bytes hold the value
+ kMaxLiteEncodeUInt32 = 5, /// One byte for prefix, the remaining 4 bytes hold the value
// Cut values for 'Lite' encoding style
kLiteCut1 = 185,
kLiteCut2 = 249,
};
- /** Find the most significant bit for 8 bits
- @param v The value to find most significant bit on
- @return The most significant bit, or -1 if no bits are set
- */
+ /** Find the most significant bit for 8 bits
+ @param v The value to find most significant bit on
+ @return The most significant bit, or -1 if no bits are set
+ */
SLANG_FORCE_INLINE static int calcMsb8(uint32_t v);
-
- /** Find the most significant bit for 32 bits
- @param v The value to find most significant bit on
- @return The most significant bit, or -1 if no bits are set
- */
+
+ /** Find the most significant bit for 32 bits
+ @param v The value to find most significant bit on
+ @return The most significant bit, or -1 if no bits are set
+ */
SLANG_FORCE_INLINE static int calcMsb32(uint32_t v);
-
- /** Calculates the 'most significant' byte ie the highest bytes that is non zero.
- Note return value is *undefined* if in is 0.
- @param in Value - cannot be 0.
- @return The byte index of the highest byte that is non zero.
- */
+
+ /** Calculates the 'most significant' byte ie the highest bytes that is non zero.
+ Note return value is *undefined* if in is 0.
+ @param in Value - cannot be 0.
+ @return The byte index of the highest byte that is non zero.
+ */
SLANG_FORCE_INLINE static int calcNonZeroMsByte32(uint32_t in);
- /** Calculates the 'most significant' byte ie the highest bytes that is non zero.
- @param in Value - cannot be 0.
- @return The byte index of the highest byte that is non zero.
- */
+ /** Calculates the 'most significant' byte ie the highest bytes that is non zero.
+ @param in Value - cannot be 0.
+ @return The byte index of the highest byte that is non zero.
+ */
SLANG_FORCE_INLINE static int calcMsByte32(uint32_t in);
- /// Calculate the size of encoding bytes
+ /// Calculate the size of encoding bytes
static size_t calcEncodeLiteSizeUInt32(const uint32_t* in, size_t num);
- /// Calculate the size of a single value
+ /// Calculate the size of a single value
static size_t calcEncodeLiteSizeUInt32(uint32_t in);
-
- /** Encodes a uint32_t as an integer
- @return the number of bytes needed to encode */
+
+ /** Encodes a uint32_t as an integer
+ @return the number of bytes needed to encode */
static int encodeLiteUInt32(uint32_t in, uint8_t out[kMaxLiteEncodeUInt32]);
- /** Decode a lite encoding.
- @param in The lite encoded bytes
- @param out Value constructed
- @return number of bytes on in consumed */
+ /** Decode a lite encoding.
+ @param in The lite encoded bytes
+ @param out Value constructed
+ @return number of bytes on in consumed */
static int decodeLiteUInt32(const uint8_t* in, uint32_t* out);
- /** Encode an array of uint32_t
- @param in The values to encode
- @param num The amount of values to encode
- @param encodeOut The buffer to hold the encoded value. MUST be large enough to hold the encoding
- @return The size of the encoding in bytes
- */
+ /** Encode an array of uint32_t
+ @param in The values to encode
+ @param num The amount of values to encode
+ @param encodeOut The buffer to hold the encoded value. MUST be large enough to hold the encoding
+ @return The size of the encoding in bytes
+ */
static size_t encodeLiteUInt32(const uint32_t* in, size_t num, uint8_t* encodeOut);
- /** Encode an array of uint32_t
- @param in The values to encode
- @param num The amount of values to encode
- @param encodeOut The buffer to hold the encoded value.
- */
+ /** Encode an array of uint32_t
+ @param in The values to encode
+ @param num The amount of values to encode
+ @param encodeOut The buffer to hold the encoded value.
+ */
static void encodeLiteUInt32(const uint32_t* in, size_t num, List<uint8_t>& encodeOut);
- /** Encode an array of uint32_t
- @param encodeIn The encoded values
- @param numValues The amount of values to be decoded (NOTE! This is the number of valuesOut, not encodeIn)
- @param valuesOut The buffer to hold the encoded value. MUST be large enough to hold the encoding
- @return The amount of bytes decoded
- */
- static size_t decodeLiteUInt32(const uint8_t* encodeIn, size_t numValues, uint32_t* valuesOut);
+ /** Encode an array of uint32_t
+ @param encodeIn The encoded values
+ @param numValues The amount of values to be decoded (NOTE! This is the number of valuesOut, not
+ encodeIn)
+ @param valuesOut The buffer to hold the encoded value. MUST be large enough to hold the encoding
+ @return The amount of bytes decoded
+ */
+ static size_t decodeLiteUInt32(const uint8_t* encodeIn, size_t numValues, uint32_t* valuesOut);
- /// Table that maps 8 bits to it's most significant bit. If 0 returns -1.
+ /// Table that maps 8 bits to it's most significant bit. If 0 returns -1.
static const int8_t s_msb8[256];
};
-#if SLANG_VC
+#if SLANG_VC
// Works on ARM and x86/64 on visual studio compiler
// ---------------------------------------------------------------------------
@@ -102,7 +104,7 @@ SLANG_FORCE_INLINE int ByteEncodeUtil::calcNonZeroMsByte32(uint32_t in)
SLANG_FORCE_INLINE int ByteEncodeUtil::calcMsByte32(uint32_t in)
{
if (in == 0)
- {
+ {
return -1;
}
// Can use intrinsic
@@ -113,7 +115,7 @@ SLANG_FORCE_INLINE int ByteEncodeUtil::calcMsByte32(uint32_t in)
}
// ---------------------------------------------------------------------------
-SLANG_FORCE_INLINE /* static */int ByteEncodeUtil::calcMsb8(uint32_t v)
+SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil::calcMsb8(uint32_t v)
{
SLANG_ASSERT((v & 0xffffff00) == 0);
if (v == 0)
@@ -126,7 +128,7 @@ SLANG_FORCE_INLINE /* static */int ByteEncodeUtil::calcMsb8(uint32_t v)
}
// ---------------------------------------------------------------------------
-SLANG_FORCE_INLINE /* static */int ByteEncodeUtil::calcMsb32(uint32_t v)
+SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil::calcMsb32(uint32_t v)
{
if (v == 0)
{
@@ -140,41 +142,36 @@ SLANG_FORCE_INLINE /* static */int ByteEncodeUtil::calcMsb32(uint32_t v)
#else
// ---------------------------------------------------------------------------
-SLANG_FORCE_INLINE /* static */int ByteEncodeUtil::calcNonZeroMsByte32(uint32_t in)
+SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil::calcNonZeroMsByte32(uint32_t in)
{
- return (in & 0xffff0000) ?
- ((in & 0xff000000) ? 3 : 2) :
- ((in & 0x0000ff00) ? 1 : 0);
+ return (in & 0xffff0000) ? ((in & 0xff000000) ? 3 : 2) : ((in & 0x0000ff00) ? 1 : 0);
}
// ---------------------------------------------------------------------------
-SLANG_FORCE_INLINE /* static */int ByteEncodeUtil::calcMsByte32(uint32_t in)
+SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil::calcMsByte32(uint32_t in)
{
- return (in & 0xffff0000) ?
- ((in & 0xff000000) ? 3 : 2) :
- ((in & 0x0000ff00) ? 1 :
- ((in == 0) ? -1 : 0));
+ return (in & 0xffff0000) ? ((in & 0xff000000) ? 3 : 2)
+ : ((in & 0x0000ff00) ? 1 : ((in == 0) ? -1 : 0));
}
// ---------------------------------------------------------------------------
-SLANG_FORCE_INLINE /* static */int ByteEncodeUtil::calcMsb8(uint32_t v)
-{
- SLANG_ASSERT((v & 0xffffff00) == 0);
- return s_msb8[v];
+SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil::calcMsb8(uint32_t v)
+{
+ SLANG_ASSERT((v & 0xffffff00) == 0);
+ return s_msb8[v];
}
// ---------------------------------------------------------------------------
-SLANG_FORCE_INLINE /* static */int ByteEncodeUtil::calcMsb32(uint32_t v)
+SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil::calcMsb32(uint32_t v)
{
- return (v & 0xffff0000) ?
- ((v & 0xff000000) ? s_msb8[v >> 24] + 24 : s_msb8[v >> 16] + 16) :
- ((v & 0x0000ff00) ? s_msb8[v >> 8] + 8 : s_msb8[v]);
+ return (v & 0xffff0000) ? ((v & 0xff000000) ? s_msb8[v >> 24] + 24 : s_msb8[v >> 16] + 16)
+ : ((v & 0x0000ff00) ? s_msb8[v >> 8] + 8 : s_msb8[v]);
}
#endif
// ---------------------------------------------------------------------------
-inline /* static */size_t ByteEncodeUtil::calcEncodeLiteSizeUInt32(uint32_t v)
+inline /* static */ size_t ByteEncodeUtil::calcEncodeLiteSizeUInt32(uint32_t v)
{
if (v < kLiteCut1)
{
diff --git a/source/core/slang-castable.cpp b/source/core/slang-castable.cpp
index f3c6541dd..ece87fe2b 100644
--- a/source/core/slang-castable.cpp
+++ b/source/core/slang-castable.cpp
@@ -1,11 +1,12 @@
// slang-castable.cpp
#include "slang-castable.h"
-namespace Slang {
+namespace Slang
+{
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CastableUtil !!!!!!!!!!!!!!!!!!!!!!!!!!! */
-/* static */ComPtr<ICastable> CastableUtil::getCastable(ISlangUnknown* unk)
+/* static */ ComPtr<ICastable> CastableUtil::getCastable(ISlangUnknown* unk)
{
SLANG_ASSERT(unk);
ComPtr<ICastable> castable;
@@ -52,8 +53,7 @@ void* UnknownCastableAdapter::castAs(const Guid& guid)
void* UnknownCastableAdapter::getInterface(const Guid& guid)
{
- if (guid == ISlangUnknown::getTypeGuid() ||
- guid == ICastable::getTypeGuid() ||
+ if (guid == ISlangUnknown::getTypeGuid() || guid == ICastable::getTypeGuid() ||
guid == IUnknownCastableAdapter::getTypeGuid())
{
return static_cast<IUnknownCastableAdapter*>(this);
diff --git a/source/core/slang-castable.h b/source/core/slang-castable.h
index e2b9c4a8e..50b41766a 100644
--- a/source/core/slang-castable.h
+++ b/source/core/slang-castable.h
@@ -3,16 +3,15 @@
#define SLANG_CASTABLE_H
+#include "../core/slang-com-object.h"
#include "slang-com-helper.h"
#include "slang-com-ptr.h"
-#include "../core/slang-com-object.h"
-
namespace Slang
{
// Dynamic cast of ICastable derived types
-template <typename T>
+template<typename T>
SLANG_FORCE_INLINE T* dynamicCast(ICastable* castable)
{
if (castable)
@@ -24,7 +23,7 @@ SLANG_FORCE_INLINE T* dynamicCast(ICastable* castable)
}
// as style cast
-template <typename T>
+template<typename T>
SLANG_FORCE_INLINE T* as(ICastable* castable)
{
if (castable)
@@ -36,34 +35,38 @@ SLANG_FORCE_INLINE T* as(ICastable* castable)
}
/* An interface for boxing values */
-class IBoxValueBase: public ICastable
+class IBoxValueBase : public ICastable
{
- SLANG_COM_INTERFACE(0x8b4aad81, 0x4934, 0x4a67, { 0xb2, 0xe2, 0xe9, 0x17, 0xfc, 0x29, 0x12, 0x54 });
+ SLANG_COM_INTERFACE(
+ 0x8b4aad81,
+ 0x4934,
+ 0x4a67,
+ {0xb2, 0xe2, 0xe9, 0x17, 0xfc, 0x29, 0x12, 0x54});
- /// Get the contained object
+ /// Get the contained object
virtual SLANG_NO_THROW void* SLANG_MCALL getValuePtr() = 0;
- /// Get the guid that represents the contained ref object
+ /// Get the guid that represents the contained ref object
virtual SLANG_NO_THROW SlangUUID SLANG_MCALL getValueTypeGuid() = 0;
};
-template <typename T>
+template<typename T>
class IBoxValue : public IBoxValueBase
{
- public:
-
+public:
SLANG_FORCE_INLINE T& get() { return *reinterpret_cast<T*>(getValuePtr()); }
SLANG_FORCE_INLINE T* getPtr() { return reinterpret_cast<T*>(getValuePtr()); }
};
// Cast into a boxed value type
-template <typename T>
+template<typename T>
SLANG_FORCE_INLINE IBoxValue<T>* asBoxValue(ICastable* castable)
{
IBoxValueBase* base = as<IBoxValueBase>(castable);
- return (base && base->getValueTypeGuid() == T::getTypeGuid()) ? static_cast<IBoxValue<T>*>(base) : nullptr;
+ return (base && base->getValueTypeGuid() == T::getTypeGuid()) ? static_cast<IBoxValue<T>*>(base)
+ : nullptr;
}
-template <typename T>
+template<typename T>
class BoxValue : public ComBaseObject, public IBoxValue<T>
{
public:
@@ -78,24 +81,23 @@ public:
BoxValue() {}
- explicit BoxValue(const T& rhs):
- m_value(rhs)
+ explicit BoxValue(const T& rhs)
+ : m_value(rhs)
{
}
protected:
- void* getInterface(const Guid& guid);
+ void* getInterface(const Guid& guid);
void* getObject(const Guid& guid);
-
+
T m_value;
};
// ------------------------------------------------------------
-template <typename T>
+template<typename T>
void* BoxValue<T>::getInterface(const Guid& guid)
{
- if (guid == ISlangUnknown::getTypeGuid() ||
- guid == ICastable::getTypeGuid() ||
+ if (guid == ISlangUnknown::getTypeGuid() || guid == ICastable::getTypeGuid() ||
guid == IBoxValueBase::getTypeGuid())
{
return static_cast<IBoxValueBase*>(this);
@@ -104,7 +106,7 @@ void* BoxValue<T>::getInterface(const Guid& guid)
}
// ------------------------------------------------------------
-template <typename T>
+template<typename T>
void* BoxValue<T>::getObject(const Guid& guid)
{
if (guid == T::getTypeGuid())
@@ -115,7 +117,7 @@ void* BoxValue<T>::getObject(const Guid& guid)
}
// ------------------------------------------------------------
-template <typename T>
+template<typename T>
void* BoxValue<T>::castAs(const Guid& guid)
{
if (auto ptr = getObject(guid))
@@ -124,22 +126,28 @@ void* BoxValue<T>::castAs(const Guid& guid)
}
return getInterface(guid);
}
-
+
/* Adapter interface to make a non castable types work as ICastable */
class IUnknownCastableAdapter : public ICastable
{
- SLANG_COM_INTERFACE(0x8b4aad81, 0x4934, 0x4a67, { 0xb2, 0xe2, 0xe9, 0x17, 0xfc, 0x29, 0x12, 0x54 });
+ SLANG_COM_INTERFACE(
+ 0x8b4aad81,
+ 0x4934,
+ 0x4a67,
+ {0xb2, 0xe2, 0xe9, 0x17, 0xfc, 0x29, 0x12, 0x54});
/// When using the adapter, this provides a way to directly get the internal no ICastable type
virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getContained() = 0;
};
-/* An adapter such that types which aren't derived from ICastable, can be used as such.
+/* An adapter such that types which aren't derived from ICastable, can be used as such.
With the following caveats.
-* the interfaces/objects of the adapter are checked *first*, so IUnknown will always be for the adapter
-* assumes when doing a queryInterface on the contained item, it will remain in scope when released (this is *not* strict COM)
+* the interfaces/objects of the adapter are checked *first*, so IUnknown will always be for the
+adapter
+* assumes when doing a queryInterface on the contained item, it will remain in scope when released
+(this is *not* strict COM)
*/
class UnknownCastableAdapter : public ComBaseObject, public IUnknownCastableAdapter
{
@@ -150,10 +158,13 @@ public:
SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// IUnknownCastableAdapter
- virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getContained() SLANG_OVERRIDE { return m_contained; }
+ virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getContained() SLANG_OVERRIDE
+ {
+ return m_contained;
+ }
- UnknownCastableAdapter(ISlangUnknown* unk):
- m_contained(unk)
+ UnknownCastableAdapter(ISlangUnknown* unk)
+ : m_contained(unk)
{
SLANG_ASSERT(unk);
}
@@ -171,15 +182,15 @@ protected:
struct CastableUtil
{
- /// Given an ISlangUnkown return as a castable interface.
- /// Can use UnknownCastableAdapter if can't queryInterface unk to ICastable
+ /// Given an ISlangUnkown return as a castable interface.
+ /// Can use UnknownCastableAdapter if can't queryInterface unk to ICastable
static ComPtr<ICastable> getCastable(ISlangUnknown* unk);
};
-// A way to clone an interface (that derives from IClonable) such that it returns an interface
+// A way to clone an interface (that derives from IClonable) such that it returns an interface
// of the same type.
-template <typename T>
+template<typename T>
SLANG_FORCE_INLINE ComPtr<T> cloneInterface(T* in)
{
SLANG_ASSERT(in);
diff --git a/source/core/slang-char-encode.cpp b/source/core/slang-char-encode.cpp
index 526c6c923..a27e7ba82 100644
--- a/source/core/slang-char-encode.cpp
+++ b/source/core/slang-char-encode.cpp
@@ -3,20 +3,23 @@
namespace Slang
{
-class Utf8CharEncoding : public CharEncoding
+class Utf8CharEncoding : public CharEncoding
{
public:
typedef CharEncoding Super;
- virtual void encode(const UnownedStringSlice& slice, List<Byte>& ioBuffer) override
- {
+ virtual void encode(const UnownedStringSlice& slice, List<Byte>& ioBuffer) override
+ {
ioBuffer.addRange((const Byte*)slice.begin(), slice.getLength());
- }
- virtual void decode(const Byte* bytes, int length, List<char>& ioChars) override
- {
+ }
+ virtual void decode(const Byte* bytes, int length, List<char>& ioChars) override
+ {
ioChars.addRange((const char*)bytes, length);
- }
- Utf8CharEncoding() : Super(CharEncodeType::UTF8) {}
+ }
+ Utf8CharEncoding()
+ : Super(CharEncodeType::UTF8)
+ {
+ }
};
class Utf32CharEncoding : public CharEncoding
@@ -24,93 +27,98 @@ class Utf32CharEncoding : public CharEncoding
public:
typedef CharEncoding Super;
- virtual void encode(const UnownedStringSlice& slice, List<Byte>& ioBuffer) override
- {
- Index ptr = 0;
- while (ptr < slice.getLength())
- {
- const Char32 codePoint = getUnicodePointFromUTF8([&]() -> Byte
- {
- if (ptr < slice.getLength())
- return slice[ptr++];
- else
- return '\0';
- });
+ virtual void encode(const UnownedStringSlice& slice, List<Byte>& ioBuffer) override
+ {
+ Index ptr = 0;
+ while (ptr < slice.getLength())
+ {
+ const Char32 codePoint = getUnicodePointFromUTF8(
+ [&]() -> Byte
+ {
+ if (ptr < slice.getLength())
+ return slice[ptr++];
+ else
+ return '\0';
+ });
// Note: Assumes byte order is same as arch byte order
ioBuffer.addRange((const Byte*)&codePoint, 4);
- }
- }
- virtual void decode(const Byte* bytes, int length, List<char>& ioBuffer) override
- {
+ }
+ }
+ virtual void decode(const Byte* bytes, int length, List<char>& ioBuffer) override
+ {
// Note: Assumes bytes is Char32 aligned
SLANG_ASSERT((size_t(bytes) & 3) == 0);
- const Char32* content = (const Char32*)bytes;
- for (int i = 0; i < (length >> 2); i++)
- {
- char buf[5];
- int count = encodeUnicodePointToUTF8(content[i], buf);
+ const Char32* content = (const Char32*)bytes;
+ for (int i = 0; i < (length >> 2); i++)
+ {
+ char buf[5];
+ int count = encodeUnicodePointToUTF8(content[i], buf);
for (int j = 0; j < count; j++)
ioBuffer.addRange(buf, count);
- }
- }
+ }
+ }
- Utf32CharEncoding() : Super(CharEncodeType::UTF32) {}
+ Utf32CharEncoding()
+ : Super(CharEncodeType::UTF32)
+ {
+ }
};
-class Utf16CharEncoding : public CharEncoding //UTF16
+class Utf16CharEncoding : public CharEncoding // UTF16
{
public:
typedef CharEncoding Super;
- Utf16CharEncoding(bool reverseOrder):
- Super(reverseOrder ? CharEncodeType::UTF16Reversed : CharEncodeType::UTF16),
- m_reverseOrder(reverseOrder)
- {}
- virtual void encode(const UnownedStringSlice& slice, List<Byte>& ioBuffer) override
- {
- Index index = 0;
- while (index < slice.getLength())
- {
- const Char32 codePoint = getUnicodePointFromUTF8([&]() -> Byte
- {
- if (index < slice.getLength())
- return slice[index++];
- else
- return '\0';
- });
-
- Char16 buffer[2];
- int count;
- if (!m_reverseOrder)
- count = encodeUnicodePointToUTF16(codePoint, buffer);
- else
- count = encodeUnicodePointToUTF16Reversed(codePoint, buffer);
+ Utf16CharEncoding(bool reverseOrder)
+ : Super(reverseOrder ? CharEncodeType::UTF16Reversed : CharEncodeType::UTF16)
+ , m_reverseOrder(reverseOrder)
+ {
+ }
+ virtual void encode(const UnownedStringSlice& slice, List<Byte>& ioBuffer) override
+ {
+ Index index = 0;
+ while (index < slice.getLength())
+ {
+ const Char32 codePoint = getUnicodePointFromUTF8(
+ [&]() -> Byte
+ {
+ if (index < slice.getLength())
+ return slice[index++];
+ else
+ return '\0';
+ });
+
+ Char16 buffer[2];
+ int count;
+ if (!m_reverseOrder)
+ count = encodeUnicodePointToUTF16(codePoint, buffer);
+ else
+ count = encodeUnicodePointToUTF16Reversed(codePoint, buffer);
ioBuffer.addRange((const Byte*)buffer, count * 2);
- }
- }
- virtual void decode(const Byte* bytes, int length, List<char>& ioBuffer) override
- {
- Index index = 0;
- while (index < length)
- {
- auto readByte = [&]() -> Byte
- {
- return (index < length) ? bytes[index++] : Byte(0);
- };
- const Char32 codePoint = m_reverseOrder ?
- getUnicodePointFromUTF16Reversed(readByte) :
- getUnicodePointFromUTF16(readByte);
-
- char buf[5];
- int count = encodeUnicodePointToUTF8(codePoint, buf);
- ioBuffer.addRange((const char*)buf, count);
- }
- }
+ }
+ }
+ virtual void decode(const Byte* bytes, int length, List<char>& ioBuffer) override
+ {
+ Index index = 0;
+ while (index < length)
+ {
+ auto readByte = [&]() -> Byte { return (index < length) ? bytes[index++] : Byte(0); };
+ const Char32 codePoint = m_reverseOrder ? getUnicodePointFromUTF16Reversed(readByte)
+ : getUnicodePointFromUTF16(readByte);
+
+ char buf[5];
+ int count = encodeUnicodePointToUTF8(codePoint, buf);
+ ioBuffer.addRange((const char*)buf, count);
+ }
+ }
private:
bool m_reverseOrder = false;
};
-/* static */CharEncodeType CharEncoding::determineEncoding(const Byte* bytes, size_t bytesCount, size_t& outOffset)
+/* static */ CharEncodeType CharEncoding::determineEncoding(
+ const Byte* bytes,
+ size_t bytesCount,
+ size_t& outOffset)
{
// TODO(JS): Assumes the bytes are suitably aligned
@@ -137,7 +145,7 @@ private:
// If we don't have a 'mark' byte then we are bit stumped. We'll look for
// null (non-terminator) bytes and assume they mean we have a 16-bit encoding
- for(size_t i = 0; i < (bytesCount-1); i += 2)
+ for (size_t i = 0; i < (bytesCount - 1); i += 2)
{
#if SLANG_LITTLE_ENDIAN
const auto low = bytes[i];
@@ -164,41 +172,42 @@ static Utf16CharEncoding _utf16Encoding(false);
static Utf16CharEncoding _utf16EncodingReversed(true);
static Utf32CharEncoding _utf32Encoding;
-/* static */CharEncoding* const CharEncoding::g_encoding[Index(CharEncodeType::CountOf)]
-{
- &_utf8Encoding, // UTF8,
- &_utf16Encoding, // UTF16,
- &_utf16EncodingReversed, // UTF16Reversed,
- &_utf32Encoding, // UTF32,
+/* static */ CharEncoding* const CharEncoding::g_encoding[Index(CharEncodeType::CountOf)]{
+ &_utf8Encoding, // UTF8,
+ &_utf16Encoding, // UTF16,
+ &_utf16EncodingReversed, // UTF16Reversed,
+ &_utf32Encoding, // UTF32,
};
CharEncoding* CharEncoding::UTF8 = &_utf8Encoding;
CharEncoding* CharEncoding::UTF16 = &_utf16Encoding;
CharEncoding* CharEncoding::UTF16Reversed = &_utf16EncodingReversed;
CharEncoding* CharEncoding::UTF32 = &_utf32Encoding;
-
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UTF8Util !!!!!!!!!!!!!!!!!!!!!!!!! */
-/* static */Index UTF8Util::calcCodePointCount(const UnownedStringSlice& in)
+/* static */ Index UTF8Util::calcCodePointCount(const UnownedStringSlice& in)
{
Index count = 0;
// Analyse with bytes...
const int8_t* cur = (const int8_t*)in.begin();
- const int8_t*const end = (const int8_t*)in.end();
+ const int8_t* const end = (const int8_t*)in.end();
while (cur < end)
{
const auto c = *cur++;
-
+
count++;
// If c < 0 it means the top bit is set... which means we have multiple bytes
if (c < 0)
{
// https://en.wikipedia.org/wiki/UTF-8
- // All continuation bytes contain exactly six bits from the code point.So the next six bits of the code point
- /// are stored in the low order six bits of the next byte, and 10 is stored in the high order two bits to
+ // All continuation bytes contain exactly six bits from the code point.So the next six
+ // bits of the code point
+ /// are stored in the low order six bits of the next byte, and 10 is stored in the high
+ /// order two bits to
// mark it as a continuation byte(so 10000010).
while (cur < end && (*cur & 0xc0) == 0x80)
@@ -217,7 +226,8 @@ Index UTF8Util::calcUTF16CharCount(const UnownedStringSlice& in)
Index readPtr = 0;
for (;;)
{
- int c = getUnicodePointFromUTF8([&]() -> Byte
+ int c = getUnicodePointFromUTF8(
+ [&]() -> Byte
{
if (readPtr < in.getLength())
return in[readPtr++];
diff --git a/source/core/slang-char-encode.h b/source/core/slang-char-encode.h
index a7cd501ab..74968a6ab 100644
--- a/source/core/slang-char-encode.h
+++ b/source/core/slang-char-encode.h
@@ -1,13 +1,13 @@
#ifndef SLANG_CORE_CHAR_ENCODE_H
#define SLANG_CORE_CHAR_ENCODE_H
-#include "slang-secure-crt.h"
#include "slang-basic.h"
+#include "slang-secure-crt.h"
namespace Slang
{
-// NOTE! Order must be kept the same to match up with
+// NOTE! Order must be kept the same to match up with
enum class CharEncodeType
{
UTF8,
@@ -17,7 +17,7 @@ enum class CharEncodeType
CountOf,
};
-template <typename ReadByteFunc>
+template<typename ReadByteFunc>
Char32 getUnicodePointFromUTF8(const ReadByteFunc& readByte)
{
Char32 codePoint = 0;
@@ -38,7 +38,7 @@ Char32 getUnicodePointFromUTF8(const ReadByteFunc& readByte)
return codePoint;
}
-template <typename ReadByteFunc>
+template<typename ReadByteFunc>
Char32 getUnicodePointFromUTF16(const ReadByteFunc& readByte)
{
uint32_t byte0 = Byte(readByte());
@@ -55,7 +55,7 @@ Char32 getUnicodePointFromUTF16(const ReadByteFunc& readByte)
return Char32(word0);
}
-template <typename ReadByteFunc>
+template<typename ReadByteFunc>
Char32 getUnicodePointFromUTF16Reversed(const ReadByteFunc& readByte)
{
uint32_t byte0 = Byte(readByte());
@@ -72,7 +72,7 @@ Char32 getUnicodePointFromUTF16Reversed(const ReadByteFunc& readByte)
return Char32(word0);
}
-template <typename ReadByteFunc>
+template<typename ReadByteFunc>
Char32 getUnicodePointFromUTF32(const ReadByteFunc& readByte)
{
uint32_t byte0 = Byte(readByte());
@@ -163,52 +163,55 @@ static const Char16 kUTF16ReversedHeader = 0xFFFE;
class CharEncoding
{
public:
- static CharEncoding* UTF8,* UTF16,* UTF16Reversed,* UTF32;
+ static CharEncoding *UTF8, *UTF16, *UTF16Reversed, *UTF32;
- /// Encode Utf8 held in slice append into ioBuffer
+ /// Encode Utf8 held in slice append into ioBuffer
virtual void encode(const UnownedStringSlice& str, List<Byte>& ioBuffer) = 0;
- /// Decode buffer into Utf8 held in ioBuffer
+ /// Decode buffer into Utf8 held in ioBuffer
virtual void decode(const Byte* buffer, int length, List<char>& ioBuffer) = 0;
- virtual ~CharEncoding() {}
+ virtual ~CharEncoding() {}
- /// Get the encoding type
+ /// Get the encoding type
CharEncodeType getEncodingType() const { return m_encodingType; }
- /// Given some bytes determines a character encoding type, based on the initial bytes.
- /// If can't be determined will assume UTF8.
- /// Outputs the offset to the first non mark in outOffset
- static CharEncodeType determineEncoding(const Byte* bytes, size_t bytesCount, size_t& outOffset);
+ /// Given some bytes determines a character encoding type, based on the initial bytes.
+ /// If can't be determined will assume UTF8.
+ /// Outputs the offset to the first non mark in outOffset
+ static CharEncodeType determineEncoding(
+ const Byte* bytes,
+ size_t bytesCount,
+ size_t& outOffset);
- /// Get the
+ /// Get the
static CharEncoding* getEncoding(CharEncodeType type) { return g_encoding[Index(type)]; }
- CharEncoding(CharEncodeType encodingType) :
- m_encodingType(encodingType)
+ CharEncoding(CharEncodeType encodingType)
+ : m_encodingType(encodingType)
{
}
protected:
-
CharEncodeType m_encodingType;
- static CharEncoding*const g_encoding[Index(CharEncodeType::CountOf)];
+ static CharEncoding* const g_encoding[Index(CharEncodeType::CountOf)];
};
struct UTF8Util
{
- /// Given a slice calculate the number of code points (unicode chars)
- ///
- /// NOTE! This doesn't check the *validity* of code points/encoding.
- /// Non valid utf8 input or ending starting in partial characters, will produce
- /// undefined results without error.
+ /// Given a slice calculate the number of code points (unicode chars)
+ ///
+ /// NOTE! This doesn't check the *validity* of code points/encoding.
+ /// Non valid utf8 input or ending starting in partial characters, will produce
+ /// undefined results without error.
static Index calcCodePointCount(const UnownedStringSlice& in);
- /// Given a slice in UTF8, calculate the number of UTF16 characters needed to represent the string.
+ /// Given a slice in UTF8, calculate the number of UTF16 characters needed to represent the
+ /// string.
static Index calcUTF16CharCount(const UnownedStringSlice& in);
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-char-util.cpp b/source/core/slang-char-util.cpp
index ea9e6dbf2..f9c61ec03 100644
--- a/source/core/slang-char-util.cpp
+++ b/source/core/slang-char-util.cpp
@@ -1,8 +1,9 @@
#include "slang-char-util.h"
-namespace Slang {
+namespace Slang
+{
-/* static */CharUtil::CharFlagMap CharUtil::makeCharFlagMap()
+/* static */ CharUtil::CharFlagMap CharUtil::makeCharFlagMap()
{
CharUtil::CharFlagMap map;
memset(&map, 0, sizeof(map));
@@ -46,11 +47,11 @@ namespace Slang {
return map;
}
-/* static */int CharUtil::_ensureLink()
+/* static */ int CharUtil::_ensureLink()
{
return makeCharFlagMap().flags[0];
}
-/* static */const CharUtil::CharFlagMap CharUtil::g_charFlagMap = makeCharFlagMap();
+/* static */ const CharUtil::CharFlagMap CharUtil::g_charFlagMap = makeCharFlagMap();
} // namespace Slang
diff --git a/source/core/slang-char-util.h b/source/core/slang-char-util.h
index 88af24426..896eb6956 100644
--- a/source/core/slang-char-util.h
+++ b/source/core/slang-char-util.h
@@ -3,7 +3,8 @@
#include "slang-string.h"
-namespace Slang {
+namespace Slang
+{
struct CharUtil
{
@@ -12,12 +13,13 @@ struct CharUtil
{
enum Enum : Flags
{
- Upper = 0x01, ///< A-Z
- Lower = 0x02, ///< a-z
- Digit = 0x04, ///< 0-9
- HorizontalWhitespace = 0x08, ///< Whitespace that can appear horizontally (ie excluding CR/LF)
- HexDigit = 0x10, ///< 0-9, a-f, A-F
- VerticalWhitespace = 0x20, ///< \n \r
+ Upper = 0x01, ///< A-Z
+ Lower = 0x02, ///< a-z
+ Digit = 0x04, ///< 0-9
+ HorizontalWhitespace =
+ 0x08, ///< Whitespace that can appear horizontally (ie excluding CR/LF)
+ HexDigit = 0x10, ///< 0-9, a-f, A-F
+ VerticalWhitespace = 0x20, ///< \n \r
};
};
@@ -26,40 +28,62 @@ struct CharUtil
SLANG_FORCE_INLINE static bool isUpper(char c) { return c >= 'A' && c <= 'Z'; }
SLANG_FORCE_INLINE static bool isHorizontalWhitespace(char c) { return c == ' ' || c == '\t'; }
SLANG_FORCE_INLINE static bool isVerticalWhitespace(char c) { return c == '\n' || c == '\r'; }
- SLANG_FORCE_INLINE static bool isWhitespace(char c) { return (getFlags(c) & (Flag::HorizontalWhitespace | Flag::VerticalWhitespace)) != 0; }
+ SLANG_FORCE_INLINE static bool isWhitespace(char c)
+ {
+ return (getFlags(c) & (Flag::HorizontalWhitespace | Flag::VerticalWhitespace)) != 0;
+ }
- /// True if it's alpha
- SLANG_FORCE_INLINE static bool isAlpha(char c) { return (getFlags(c) & (Flag::Upper | Flag::Lower)) != 0; }
- /// True if it's alpha or a digit
- SLANG_FORCE_INLINE static bool isAlphaOrDigit(char c) { return (getFlags(c) & (Flag::Upper | Flag::Lower | Flag::Digit)) != 0; }
+ /// True if it's alpha
+ SLANG_FORCE_INLINE static bool isAlpha(char c)
+ {
+ return (getFlags(c) & (Flag::Upper | Flag::Lower)) != 0;
+ }
+ /// True if it's alpha or a digit
+ SLANG_FORCE_INLINE static bool isAlphaOrDigit(char c)
+ {
+ return (getFlags(c) & (Flag::Upper | Flag::Lower | Flag::Digit)) != 0;
+ }
- /// True if the character is a valid hex character
- SLANG_FORCE_INLINE static bool isHexDigit(char c) { return (getFlags(c) & Flag::HexDigit) != 0; }
+ /// True if the character is a valid hex character
+ SLANG_FORCE_INLINE static bool isHexDigit(char c)
+ {
+ return (getFlags(c) & Flag::HexDigit) != 0;
+ }
- /// True if the character is an octal digit
+ /// True if the character is an octal digit
SLANG_FORCE_INLINE static bool isOctalDigit(char c) { return c >= '0' && c <= '7'; }
- /// For a given character get the associated flags
+ /// For a given character get the associated flags
SLANG_FORCE_INLINE static Flags getFlags(char c) { return g_charFlagMap.flags[size_t(c)]; }
- /// Given a character return the lower case equivalent
- SLANG_FORCE_INLINE static char toLower(char c) { return (c >= 'A' && c <= 'Z') ? (c -'A' + 'a') : c; }
- /// Given a character return the upper case equivalent
- SLANG_FORCE_INLINE static char toUpper(char c) { return (c >= 'a' && c <= 'z') ? (c -'a' + 'A') : c; }
+ /// Given a character return the lower case equivalent
+ SLANG_FORCE_INLINE static char toLower(char c)
+ {
+ return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
+ }
+ /// Given a character return the upper case equivalent
+ SLANG_FORCE_INLINE static char toUpper(char c)
+ {
+ return (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') : c;
+ }
- /// Given a value between 0-15 inclusive returns the hex digit. Uses lower case hex.
- SLANG_FORCE_INLINE static char getHexChar(Index i) { SLANG_ASSERT((i & ~Index(0xf)) == 0); return char(i >= 10 ? (i - 10 + 'a') : (i + '0')); }
+ /// Given a value between 0-15 inclusive returns the hex digit. Uses lower case hex.
+ SLANG_FORCE_INLINE static char getHexChar(Index i)
+ {
+ SLANG_ASSERT((i & ~Index(0xf)) == 0);
+ return char(i >= 10 ? (i - 10 + 'a') : (i + '0'));
+ }
- /// Returns the value if c interpretted as a decimal digit
- /// If c is not a valid digit returns -1
+ /// Returns the value if c interpretted as a decimal digit
+ /// If c is not a valid digit returns -1
inline static int getDecimalDigitValue(char c) { return isDigit(c) ? (c - '0') : -1; }
- /// Returns the value if c interpretted as a hex digit
- /// If c is not a valid hex returns -1
+ /// Returns the value if c interpretted as a hex digit
+ /// If c is not a valid hex returns -1
inline static int getHexDigitValue(char c);
-
- /// Returns the value if c interpretted as a octal digit
- /// If c is not a valid octal returns -1
+
+ /// Returns the value if c interpretted as a octal digit
+ /// If c is not a valid octal returns -1
inline static int getOctalDigitValue(char c) { return isOctalDigit(c) ? (c - '0') : -1; }
struct CharFlagMap
@@ -69,16 +93,17 @@ struct CharUtil
static CharFlagMap makeCharFlagMap();
- // HACK!
- // JS: Many of the inlined functions of CharUtil just access a global map. That referencing this global is *NOT* enough to
- // link correctly with CharUtil on linux for a shared library. Caling this function can force linkage.
+ // HACK!
+ // JS: Many of the inlined functions of CharUtil just access a global map. That referencing this
+ // global is *NOT* enough to link correctly with CharUtil on linux for a shared library. Caling
+ // this function can force linkage.
static int _ensureLink();
static const CharFlagMap g_charFlagMap;
};
-
+
// ------------------------------------------------------------------------------------
-inline /* static */int CharUtil::getHexDigitValue(char c)
+inline /* static */ int CharUtil::getHexDigitValue(char c)
{
if (c >= '0' && c <= '9')
{
diff --git a/source/core/slang-chunked-list.h b/source/core/slang-chunked-list.h
index d414eaefb..95324f8c9 100644
--- a/source/core/slang-chunked-list.h
+++ b/source/core/slang-chunked-list.h
@@ -1,16 +1,15 @@
#ifndef SLANG_CORE_CHUNKED_LIST_H
#define SLANG_CORE_CHUNKED_LIST_H
-#include "slang.h"
-
#include "slang-allocator.h"
#include "slang-array-view.h"
#include "slang-math.h"
+#include "slang.h"
namespace Slang
{
// Items stored in a ChunkedList are guaranteed to have fixed address.
-template <typename T, uint32_t defaultChunkSize = 16, typename TAllocator = StandardAllocator>
+template<typename T, uint32_t defaultChunkSize = 16, typename TAllocator = StandardAllocator>
class ChunkedList
{
private:
@@ -21,10 +20,7 @@ private:
uint32_t size = 0;
uint32_t capacity = defaultChunkSize;
Chunk* next = nullptr;
- T* begin()
- {
- return reinterpret_cast<T*>(this + 1);
- }
+ T* begin() { return reinterpret_cast<T*>(this + 1); }
T* end() { return begin() + size; }
};
@@ -60,24 +56,26 @@ private:
public:
typedef ChunkedList<T, defaultChunkSize, TAllocator> ThisType;
ChunkedList()
- : m_lastChunk(&m_firstChunk)
- , m_count(0)
- {}
- template <typename... Args> ChunkedList(const T& val, Args... args) { _init(val, args...); }
+ : m_lastChunk(&m_firstChunk), m_count(0)
+ {
+ }
+ template<typename... Args>
+ ChunkedList(const T& val, Args... args)
+ {
+ _init(val, args...);
+ }
ChunkedList(const ThisType& list)
- : m_lastChunk(&m_firstChunk)
- , m_count(0)
+ : m_lastChunk(&m_firstChunk), m_count(0)
{
this->operator=(list);
}
ChunkedList(ThisType&& list)
- : m_lastChunk(&m_firstChunk)
- , m_count(0)
+ : m_lastChunk(&m_firstChunk), m_count(0)
{
this->operator=(static_cast<ThisType&&>(list));
}
~ChunkedList() { _deallocateBuffer(); }
- template <int _otherShortListSize, typename TOtherAllocator>
+ template<int _otherShortListSize, typename TOtherAllocator>
ThisType& operator=(const ChunkedList<T, _otherShortListSize, TOtherAllocator>& list)
{
clearAndDeallocate();
@@ -213,7 +211,8 @@ public:
return result;
}
- template <typename TContainer> T* addRange(const TContainer& list)
+ template<typename TContainer>
+ T* addRange(const TContainer& list)
{
Chunk* chunk = _maybeReserveForAdd((uint32_t)list.getCount());
auto result = chunk->begin() + chunk->size;
@@ -235,7 +234,6 @@ public:
}
private:
-
Index m_count = 0; ///< The amount of elements
FirstChunk m_firstChunk;
Chunk* m_lastChunk = &m_firstChunk;
@@ -262,7 +260,8 @@ private:
return AllocateMethod<T, TAllocator>::deallocateArray(ptr, count);
}
- template <typename... Args> void _init(const T& val, Args... args)
+ template<typename... Args>
+ void _init(const T& val, Args... args)
{
add(val);
_init(args...);
diff --git a/source/core/slang-com-object.h b/source/core/slang-com-object.h
index 617b7ccca..801af61a4 100644
--- a/source/core/slang-com-object.h
+++ b/source/core/slang-com-object.h
@@ -2,34 +2,35 @@
#define SLANG_COM_OBJECT_H
#include "slang-basic.h"
+
#include <atomic>
namespace Slang
{
-/// A base class for COM interfaces that require atomic ref counting
+/// A base class for COM interfaces that require atomic ref counting
/// and are *NOT* derived from RefObject
class ComBaseObject
{
public:
-
- /// If assigned the the ref count is *NOT* copied
+ /// If assigned the the ref count is *NOT* copied
ComBaseObject& operator=(const ComBaseObject&) { return *this; }
- /// Copy Ctor, does not copy ref count
- ComBaseObject(const ComBaseObject&) :
- m_refCount(0)
- {}
+ /// Copy Ctor, does not copy ref count
+ ComBaseObject(const ComBaseObject&)
+ : m_refCount(0)
+ {
+ }
- /// Default Ctor sets with no refs
+ /// Default Ctor sets with no refs
ComBaseObject()
: m_refCount(0)
- {}
+ {
+ }
- /// Dtor needs to be virtual to avoid needing to
- /// Implement release for all derived types.
- virtual ~ComBaseObject()
- {}
+ /// Dtor needs to be virtual to avoid needing to
+ /// Implement release for all derived types.
+ virtual ~ComBaseObject() {}
protected:
inline uint32_t _releaseImpl();
@@ -50,7 +51,7 @@ inline uint32_t ComBaseObject::_releaseImpl()
return count;
}
-#define SLANG_COM_BASE_IUNKNOWN_QUERY_INTERFACE \
+#define SLANG_COM_BASE_IUNKNOWN_QUERY_INTERFACE \
SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) \
SLANG_OVERRIDE \
{ \
@@ -63,10 +64,16 @@ inline uint32_t ComBaseObject::_releaseImpl()
} \
return SLANG_E_NO_INTERFACE; \
}
-#define SLANG_COM_BASE_IUNKNOWN_ADD_REF \
- SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return ++m_refCount; }
-#define SLANG_COM_BASE_IUNKNOWN_RELEASE \
- SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return _releaseImpl(); }
+#define SLANG_COM_BASE_IUNKNOWN_ADD_REF \
+ SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE \
+ { \
+ return ++m_refCount; \
+ }
+#define SLANG_COM_BASE_IUNKNOWN_RELEASE \
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE \
+ { \
+ return _releaseImpl(); \
+ }
#define SLANG_COM_BASE_IUNKNOWN_ALL \
SLANG_COM_BASE_IUNKNOWN_QUERY_INTERFACE \
SLANG_COM_BASE_IUNKNOWN_ADD_REF \
@@ -82,11 +89,12 @@ protected:
public:
ComObject()
: comRefCount(0)
- {}
- ComObject(const ComObject& rhs) :
- RefObject(rhs),
- comRefCount(0)
- {}
+ {
+ }
+ ComObject(const ComObject& rhs)
+ : RefObject(rhs), comRefCount(0)
+ {
+ }
ComObject& operator=(const ComObject&) { return *this; }
@@ -125,10 +133,16 @@ public:
} \
return SLANG_E_NO_INTERFACE; \
}
-#define SLANG_COM_OBJECT_IUNKNOWN_ADD_REF \
- SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return addRefImpl(); }
-#define SLANG_COM_OBJECT_IUNKNOWN_RELEASE \
- SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return releaseImpl(); }
+#define SLANG_COM_OBJECT_IUNKNOWN_ADD_REF \
+ SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE \
+ { \
+ return addRefImpl(); \
+ }
+#define SLANG_COM_OBJECT_IUNKNOWN_RELEASE \
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE \
+ { \
+ return releaseImpl(); \
+ }
#define SLANG_COM_OBJECT_IUNKNOWN_ALL \
SLANG_COM_OBJECT_IUNKNOWN_QUERY_INTERFACE \
SLANG_COM_OBJECT_IUNKNOWN_ADD_REF \
diff --git a/source/core/slang-command-line.cpp b/source/core/slang-command-line.cpp
index bfd9ed11a..8269d37c5 100644
--- a/source/core/slang-command-line.cpp
+++ b/source/core/slang-command-line.cpp
@@ -1,17 +1,17 @@
// slang-command-line.cpp
#include "slang-command-line.h"
+#include "slang-com-helper.h"
#include "slang-process.h"
-
-#include "slang-string.h"
#include "slang-string-escape-util.h"
#include "slang-string-util.h"
+#include "slang-string.h"
-#include "slang-com-helper.h"
-
-namespace Slang {
+namespace Slang
+{
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ExecutableLocation !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ExecutableLocation !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
void ExecutableLocation::set(const String& dir, const String& name)
{
diff --git a/source/core/slang-command-line.h b/source/core/slang-command-line.h
index 163daf710..804266ad1 100644
--- a/source/core/slang-command-line.h
+++ b/source/core/slang-command-line.h
@@ -2,10 +2,11 @@
#ifndef SLANG_COMMAND_LINE_H
#define SLANG_COMMAND_LINE_H
-#include "slang-string.h"
#include "slang-list.h"
+#include "slang-string.h"
-namespace Slang {
+namespace Slang
+{
struct ExecutableLocation
{
@@ -13,43 +14,67 @@ struct ExecutableLocation
enum Type
{
- Unknown, ///< Not specified
- Path, ///< The executable is set as a path (ie won't be searched for)
- Name, ///< The executable is passed as a name which will be searched for
+ Unknown, ///< Not specified
+ Path, ///< The executable is set as a path (ie won't be searched for)
+ Name, ///< The executable is passed as a name which will be searched for
};
- /// Set the executable path.
- /// NOTE! On some targets the executable path *must* include an extension to be able to start as a process
- void setPath(const String& path) { m_type = Type::Path; m_pathOrName = path; }
+ /// Set the executable path.
+ /// NOTE! On some targets the executable path *must* include an extension to be able to start as
+ /// a process
+ void setPath(const String& path)
+ {
+ m_type = Type::Path;
+ m_pathOrName = path;
+ }
- /// Set a filename (such that the path will be looked up)
- void setName(const String& filename) { m_type = Type::Name; m_pathOrName = filename; }
+ /// Set a filename (such that the path will be looked up)
+ void setName(const String& filename)
+ {
+ m_type = Type::Name;
+ m_pathOrName = filename;
+ }
- void set(Type type, const String& pathOrName) { m_type = type; m_pathOrName = pathOrName; }
+ void set(Type type, const String& pathOrName)
+ {
+ m_type = type;
+ m_pathOrName = pathOrName;
+ }
- /// Set the executable path from a base directory and an executable name (no suffix such as '.exe' needed)
+ /// Set the executable path from a base directory and an executable name (no suffix such as
+ /// '.exe' needed)
void set(const String& dir, const String& name);
- /// Determines if it's a name or a path when it sets
+ /// Determines if it's a name or a path when it sets
void set(const String& nameOrPath);
- /// Append as text to out.
+ /// Append as text to out.
void append(StringBuilder& out) const;
- /// Reset state to be same as ctor
- void reset() { m_type = Type::Unknown; m_pathOrName = String(); }
+ /// Reset state to be same as ctor
+ void reset()
+ {
+ m_type = Type::Unknown;
+ m_pathOrName = String();
+ }
- /// Equality means exactly the same definition.
- /// *NOT* that exactly the same executable is specified
- bool operator==(const ThisType& rhs) const { return m_type == rhs.m_type && m_pathOrName == rhs.m_pathOrName; }
+ /// Equality means exactly the same definition.
+ /// *NOT* that exactly the same executable is specified
+ bool operator==(const ThisType& rhs) const
+ {
+ return m_type == rhs.m_type && m_pathOrName == rhs.m_pathOrName;
+ }
bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
ExecutableLocation() {}
- ExecutableLocation(const String& dir, const String& name) { set(dir, name); }
- ExecutableLocation(Type type, const String& pathOrName) : m_type(type), m_pathOrName(pathOrName) {}
+ ExecutableLocation(const String& dir, const String& name) { set(dir, name); }
+ ExecutableLocation(Type type, const String& pathOrName)
+ : m_type(type), m_pathOrName(pathOrName)
+ {
+ }
explicit ExecutableLocation(const String& nameOrPath) { set(nameOrPath); }
-
+
Type m_type = Type::Unknown;
String m_pathOrName;
};
@@ -58,42 +83,52 @@ struct CommandLine
{
typedef CommandLine ThisType;
- /// Add args - assumed unescaped
+ /// Add args - assumed unescaped
void addArg(const String& in) { m_args.add(in); }
- void addArgs(const String* args, Int argsCount) { for (Int i = 0; i < argsCount; ++i) addArg(args[i]); }
+ void addArgs(const String* args, Int argsCount)
+ {
+ for (Int i = 0; i < argsCount; ++i)
+ addArg(args[i]);
+ }
void addArgIfNotFound(const String& in);
- /// Find the index of an arg which is exact match for slice
- SLANG_INLINE Index findArgIndex(const UnownedStringSlice& slice) const { return m_args.indexOf(slice); }
+ /// Find the index of an arg which is exact match for slice
+ SLANG_INLINE Index findArgIndex(const UnownedStringSlice& slice) const
+ {
+ return m_args.indexOf(slice);
+ }
- /// For handling args where the switch is placed directly in front of the path
- void addPrefixPathArg(const char* prefix, const String& path, const char* pathPostfix = nullptr);
+ /// For handling args where the switch is placed directly in front of the path
+ void addPrefixPathArg(
+ const char* prefix,
+ const String& path,
+ const char* pathPostfix = nullptr);
- /// Get the total number of args
+ /// Get the total number of args
SLANG_FORCE_INLINE Index getArgCount() const { return m_args.getCount(); }
- /// Reset to the initial state
- void reset() { *this = CommandLine(); }
+ /// Reset to the initial state
+ void reset() { *this = CommandLine(); }
- /// Append the args
+ /// Append the args
void appendArgs(StringBuilder& out) const;
- /// Append the command line to out
+ /// Append the command line to out
void append(StringBuilder& out) const;
- /// convert into a string
+ /// convert into a string
String toString() const;
- /// Convert just the args to string
+ /// Convert just the args to string
String toStringArgs() const;
- /// Set an executable location
+ /// Set an executable location
void setExecutableLocation(const ExecutableLocation& loc) { m_executableLocation = loc; }
- ExecutableLocation m_executableLocation; ///< The executable location
- List<String> m_args; ///< The arguments (Stored *unescaped*)
+ ExecutableLocation m_executableLocation; ///< The executable location
+ List<String> m_args; ///< The arguments (Stored *unescaped*)
};
-}
+} // namespace Slang
#endif // SLANG_COMMAND_LINE_H
diff --git a/source/core/slang-command-options-writer.cpp b/source/core/slang-command-options-writer.cpp
index afa46db64..f46bcc56c 100644
--- a/source/core/slang-command-options-writer.cpp
+++ b/source/core/slang-command-options-writer.cpp
@@ -2,18 +2,26 @@
#include "slang-command-options-writer.h"
-#include "slang-string-util.h"
-#include "slang-char-util.h"
#include "slang-byte-encode-util.h"
+#include "slang-char-util.h"
+#include "slang-string-util.h"
+
+namespace Slang
+{
-namespace Slang {
-
-namespace { // anonymous
+namespace
+{ // anonymous
typedef CommandOptionsWriter::Style Style;
-} // anonymous
+} // namespace
-static bool _isMarkdown(Style style) { return style == Style::Markdown || style == Style::NoLinkMarkdown; }
-static bool _hasLinks(Style style) { return style == Style::Markdown; }
+static bool _isMarkdown(Style style)
+{
+ return style == Style::Markdown || style == Style::NoLinkMarkdown;
+}
+static bool _hasLinks(Style style)
+{
+ return style == Style::Markdown;
+}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MarkdownCommandOptionsWriter !!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -25,17 +33,17 @@ public:
typedef uint32_t LinkFlags;
struct LinkFlag
{
- enum Enum
+ enum Enum
{
Category = 0x1,
- Option = 0x2,
+ Option = 0x2,
All = Category | Option,
};
};
- MarkdownCommandOptionsWriter(const Options& options):
- Super(options)
+ MarkdownCommandOptionsWriter(const Options& options)
+ : Super(options)
{
}
@@ -45,15 +53,17 @@ protected:
virtual void appendDescriptionImpl() SLANG_OVERRIDE;
void _appendParagraph(const UnownedStringSlice& text, LinkFlags flags = LinkFlag::All);
- void _appendParagraph(const ConstArrayView<UnownedStringSlice>& words, LinkFlags flags = LinkFlag::All);
+ void _appendParagraph(
+ const ConstArrayView<UnownedStringSlice>& words,
+ LinkFlags flags = LinkFlag::All);
- void _appendMaybeLink(const UnownedStringSlice& word, LinkFlags linkFlags);
+ void _appendMaybeLink(const UnownedStringSlice& word, LinkFlags linkFlags);
void _appendText(const UnownedStringSlice& text);
void _appendDescriptionForCategory(Index categoryIndex);
UnownedStringSlice _getLinkName(CommandOptions::LookupKind kind, Index index);
UnownedStringSlice _getLinkName(const NameKey& key, Index index);
-
+
void _appendQuickLinks();
bool m_hasLinks = false;
@@ -91,15 +101,15 @@ static bool _needsMarkdownEscape(const UnownedStringSlice& text)
{
switch (c)
{
- case '<':
- case '>':
- case '&':
- case '[':
- case ']':
+ case '<':
+ case '>':
+ case '&':
+ case '[':
+ case ']':
{
return true;
}
- default: break;
+ default: break;
}
}
@@ -115,12 +125,12 @@ void _appendEscapedMarkdown(const UnownedStringSlice& text, StringBuilder& ioBuf
{
switch (c)
{
- case '<': ioBuf << "&lt;"; break;
- case '>': ioBuf << "&gt;"; break;
- case '&': ioBuf << "&amp;"; break;
- case '[': ioBuf << "\\["; break;
- case ']': ioBuf << "\\]"; break;
- default: ioBuf << c;
+ case '<': ioBuf << "&lt;"; break;
+ case '>': ioBuf << "&gt;"; break;
+ case '&': ioBuf << "&amp;"; break;
+ case '[': ioBuf << "\\["; break;
+ case ']': ioBuf << "\\]"; break;
+ default: ioBuf << c;
}
}
}
@@ -149,7 +159,9 @@ void MarkdownCommandOptionsWriter::_appendQuickLinks()
m_builder << "\n";
}
-void MarkdownCommandOptionsWriter::_appendParagraph(const UnownedStringSlice& text, LinkFlags linkFlags)
+void MarkdownCommandOptionsWriter::_appendParagraph(
+ const UnownedStringSlice& text,
+ LinkFlags linkFlags)
{
List<UnownedStringSlice> words;
StringUtil::splitOnWhitespace(text, words);
@@ -171,12 +183,16 @@ static UnownedStringSlice _trimPunctuation(const UnownedStringSlice& word)
const char* start = word.begin();
const char* end = word.end();
- while (start < end && _isStartPunctionation(*start)) start++;
- while (end > start && _isEndPunctionation(end[-1])) --end;
+ while (start < end && _isStartPunctionation(*start))
+ start++;
+ while (end > start && _isEndPunctionation(end[-1]))
+ --end;
return UnownedStringSlice(start, end);
}
-void MarkdownCommandOptionsWriter::_appendMaybeLink(const UnownedStringSlice& inWord, LinkFlags linkFlags)
+void MarkdownCommandOptionsWriter::_appendMaybeLink(
+ const UnownedStringSlice& inWord,
+ LinkFlags linkFlags)
{
if (linkFlags)
{
@@ -190,17 +206,27 @@ void MarkdownCommandOptionsWriter::_appendMaybeLink(const UnownedStringSlice& in
// Look for options
if (trimmedWord[0] == '-' && (linkFlags & LinkFlag::Option))
{
- index = m_commandOptions->findTargetIndexByName(LookupKind::Option, trimmedWord, &nameKey);
+ index = m_commandOptions->findTargetIndexByName(
+ LookupKind::Option,
+ trimmedWord,
+ &nameKey);
}
- else if (trimmedWord[0] == '<' && trimmedWord[trimmedWord.getLength() - 1] == '>' && (linkFlags & LinkFlag::Category))
+ else if (
+ trimmedWord[0] == '<' && trimmedWord[trimmedWord.getLength() - 1] == '>' &&
+ (linkFlags & LinkFlag::Category))
{
- index = m_commandOptions->findTargetIndexByName(LookupKind::Category, trimmedWord.subString(1, trimmedWord.getLength() - 2), &nameKey);
+ index = m_commandOptions->findTargetIndexByName(
+ LookupKind::Category,
+ trimmedWord.subString(1, trimmedWord.getLength() - 2),
+ &nameKey);
}
-
+
if (index > 0)
{
// Append before the link
- _appendEscapedMarkdown(UnownedStringSlice(inWord.begin(), trimmedWord.begin()), m_builder);
+ _appendEscapedMarkdown(
+ UnownedStringSlice(inWord.begin(), trimmedWord.begin()),
+ m_builder);
// Make into a link
m_builder << "[";
@@ -208,7 +234,9 @@ void MarkdownCommandOptionsWriter::_appendMaybeLink(const UnownedStringSlice& in
m_builder << "](#" << _getLinkName(nameKey, index) << ")";
// Append after the link
- _appendEscapedMarkdown(UnownedStringSlice(trimmedWord.end(), inWord.end()), m_builder);
+ _appendEscapedMarkdown(
+ UnownedStringSlice(trimmedWord.end(), inWord.end()),
+ m_builder);
return;
}
}
@@ -217,7 +245,9 @@ void MarkdownCommandOptionsWriter::_appendMaybeLink(const UnownedStringSlice& in
_appendEscapedMarkdown(inWord, m_builder);
}
-void MarkdownCommandOptionsWriter::_appendParagraph(const ConstArrayView<UnownedStringSlice>& words, LinkFlags linkFlags)
+void MarkdownCommandOptionsWriter::_appendParagraph(
+ const ConstArrayView<UnownedStringSlice>& words,
+ LinkFlags linkFlags)
{
if (m_hasLinks && linkFlags)
{
@@ -271,19 +301,21 @@ void MarkdownCommandOptionsWriter::_appendDescriptionForCategory(Index categoryI
if (m_hasLinks)
{
// Output anchor
- m_builder << "<a id=\"" << _getLinkName(LookupKind::Category, categoryIndex) << "\"></a>\n";
+ m_builder << "<a id=\"" << _getLinkName(LookupKind::Category, categoryIndex)
+ << "\"></a>\n";
}
m_builder << "# " << category.name << "\n\n";
-
+
// If there is a description output, making \n split paragraphs
if (category.description.getLength() > 0)
{
_appendText(category.description);
- }
+ }
}
- for (Index optionIndex = category.optionStartIndex; optionIndex < category.optionEndIndex; ++optionIndex)
+ for (Index optionIndex = category.optionStartIndex; optionIndex < category.optionEndIndex;
+ ++optionIndex)
{
const auto& option = options.getOptionAt(optionIndex);
@@ -294,7 +326,7 @@ void MarkdownCommandOptionsWriter::_appendDescriptionForCategory(Index categoryI
if (isValue)
{
m_builder << "* ";
- // Output all the names
+ // Output all the names
m_builder << "`";
StringUtil::join(names.getBuffer(), names.getCount(), toSlice("`, `"), m_builder);
m_builder << "` ";
@@ -303,7 +335,8 @@ void MarkdownCommandOptionsWriter::_appendDescriptionForCategory(Index categoryI
{
if (m_hasLinks)
{
- m_builder << "<a id=\"" << _getLinkName(LookupKind::Option, optionIndex) << "\"></a>\n";
+ m_builder << "<a id=\"" << _getLinkName(LookupKind::Option, optionIndex)
+ << "\"></a>\n";
}
m_builder << "## ";
@@ -322,17 +355,24 @@ void MarkdownCommandOptionsWriter::_appendDescriptionForCategory(Index categoryI
const char* cur = option.usage.begin();
for (auto usedCategory : usedCategories)
{
- _appendEscapedMarkdown(UnownedStringSlice(cur, usedCategory.begin()), m_builder);
+ _appendEscapedMarkdown(
+ UnownedStringSlice(cur, usedCategory.begin()),
+ m_builder);
// Now do the link
- const Index usedCategoryIndex = options.findCategoryByName(usedCategory);
+ const Index usedCategoryIndex =
+ options.findCategoryByName(usedCategory);
- m_builder << "[" << usedCategory << "](#" << _getLinkName(LookupKind::Category, usedCategoryIndex) << ")";
+ m_builder << "[" << usedCategory << "](#"
+ << _getLinkName(LookupKind::Category, usedCategoryIndex)
+ << ")";
cur = usedCategory.end();
}
- _appendEscapedMarkdown(UnownedStringSlice(cur, option.usage.end()), m_builder);
+ _appendEscapedMarkdown(
+ UnownedStringSlice(cur, option.usage.end()),
+ m_builder);
}
else
{
@@ -370,9 +410,9 @@ UnownedStringSlice MarkdownCommandOptionsWriter::_getLinkName(const NameKey& key
return m_pool.getSlice(*ptr);
}
- UnownedStringSlice prefix = (key.kind == CommandOptions::LookupKind::Category) ?
- m_commandOptions->getFirstNameForCategory(index) :
- m_commandOptions->getFirstNameForOption(index);
+ UnownedStringSlice prefix = (key.kind == CommandOptions::LookupKind::Category)
+ ? m_commandOptions->getFirstNameForCategory(index)
+ : m_commandOptions->getFirstNameForOption(index);
prefix = prefix.trim('-');
if (prefix.getLength() == 0)
@@ -406,17 +446,17 @@ UnownedStringSlice MarkdownCommandOptionsWriter::_getLinkName(const NameKey& key
return m_pool.getSlice(handle);
}
-UnownedStringSlice MarkdownCommandOptionsWriter::_getLinkName(CommandOptions::LookupKind kind, Index index)
+UnownedStringSlice MarkdownCommandOptionsWriter::_getLinkName(
+ CommandOptions::LookupKind kind,
+ Index index)
{
auto& options = *m_commandOptions;
- // Set up the name key
- const auto key = (kind == LookupKind::Category) ?
- options.getNameKeyForCategory(index) :
- options.getNameKeyForOption(index);
-
- return _getLinkName(key, index);
+ // Set up the name key
+ const auto key = (kind == LookupKind::Category) ? options.getNameKeyForCategory(index)
+ : options.getNameKeyForOption(index);
+ return _getLinkName(key, index);
}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TextCommandOptionsWriter !!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -425,11 +465,12 @@ class TextCommandOptionsWriter : public CommandOptionsWriter
{
public:
typedef CommandOptionsWriter Super;
-
- TextCommandOptionsWriter(const Options& options) :
- Super(options)
+
+ TextCommandOptionsWriter(const Options& options)
+ : Super(options)
{
}
+
protected:
// CommandOptionsWriter
virtual void appendDescriptionForCategoryImpl(Index categoryIndex) SLANG_OVERRIDE;
@@ -580,26 +621,24 @@ void TextCommandOptionsWriter::_appendText(Count indentCount, const UnownedStrin
typedef CommandOptionsWriter::Style Style;
-static const NamesDescriptionValue s_styleInfos[] =
-{
- { ValueInt(Style::Text), "text", "Text suitable for output to a terminal" },
- { ValueInt(Style::Markdown), "markdown", "Markdown" },
- { ValueInt(Style::NoLinkMarkdown), "no-link-markdown", "Markdown without links" },
+static const NamesDescriptionValue s_styleInfos[] = {
+ {ValueInt(Style::Text), "text", "Text suitable for output to a terminal"},
+ {ValueInt(Style::Markdown), "markdown", "Markdown"},
+ {ValueInt(Style::NoLinkMarkdown), "no-link-markdown", "Markdown without links"},
};
-/* static */ConstArrayView<NamesDescriptionValue> CommandOptionsWriter::getStyleInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> CommandOptionsWriter::getStyleInfos()
{
return makeConstArrayView(s_styleInfos);
}
-CommandOptionsWriter::CommandOptionsWriter(const Options& options) :
- m_pool(StringSlicePool::Style::Default),
- m_options(options)
+CommandOptionsWriter::CommandOptionsWriter(const Options& options)
+ : m_pool(StringSlicePool::Style::Default), m_options(options)
{
m_options.indent = m_pool.addAndGetSlice(options.indent);
}
-/* static */RefPtr<CommandOptionsWriter> CommandOptionsWriter::create(const Options& options)
+/* static */ RefPtr<CommandOptionsWriter> CommandOptionsWriter::create(const Options& options)
{
if (_isMarkdown(options.style))
{
@@ -611,7 +650,9 @@ CommandOptionsWriter::CommandOptionsWriter(const Options& options) :
}
}
-void CommandOptionsWriter::appendDescriptionForCategory(CommandOptions* options, Index categoryIndex)
+void CommandOptionsWriter::appendDescriptionForCategory(
+ CommandOptions* options,
+ Index categoryIndex)
{
m_commandOptions = options;
appendDescriptionForCategoryImpl(categoryIndex);
@@ -667,7 +708,10 @@ void CommandOptionsWriter::_requireIndent(Count indentCount)
}
}
-void CommandOptionsWriter::_appendWrappedIndented(Count indentCount, List<UnownedStringSlice>& slices, const UnownedStringSlice& delimit)
+void CommandOptionsWriter::_appendWrappedIndented(
+ Count indentCount,
+ List<UnownedStringSlice>& slices,
+ const UnownedStringSlice& delimit)
{
Count lineLength = _getCurrentLineLength();
@@ -708,5 +752,3 @@ void CommandOptionsWriter::_appendWrappedIndented(Count indentCount, List<Unowne
}
} // namespace Slang
-
-
diff --git a/source/core/slang-command-options-writer.h b/source/core/slang-command-options-writer.h
index eb9a2795f..5452d7617 100644
--- a/source/core/slang-command-options-writer.h
+++ b/source/core/slang-command-options-writer.h
@@ -19,51 +19,54 @@ public:
Markdown, ///< Markdown
NoLinkMarkdown, ///< Markdown without links
};
-
+
static ConstArrayView<NamesDescriptionValue> getStyleInfos();
struct Options
{
- Style style = Style::Text; ///< The style
- Index lineLength = 120; ///< The maximum amount of characters on a line
- UnownedStringSlice indent = toSlice(" ");;
+ Style style = Style::Text; ///< The style
+ Index lineLength = 120; ///< The maximum amount of characters on a line
+ UnownedStringSlice indent = toSlice(" ");
+ ;
};
- /// Append descirption for a category
+ /// Append descirption for a category
void appendDescriptionForCategory(CommandOptions* options, Index categoryIndex);
- /// Appends a description of all of the options
+ /// Appends a description of all of the options
void appendDescription(CommandOptions* options);
- /// Get the builder that string is being written to
+ /// Get the builder that string is being written to
StringBuilder& getBuilder() { return m_builder; }
static RefPtr<CommandOptionsWriter> create(const Options& options);
-
-protected:
- /// Append descirption for a category
+protected:
+ /// Append descirption for a category
virtual void appendDescriptionForCategoryImpl(Index categoryIndex) = 0;
- /// Appends a description of all of the options
+ /// Appends a description of all of the options
virtual void appendDescriptionImpl() = 0;
// Ctor, use create to create a writer
CommandOptionsWriter(const Options& options);
- /// Get the length of the current line in ascii chars/bytes
+ /// Get the length of the current line in ascii chars/bytes
Count _getCurrentLineLength();
- /// Indentation/wrapping
+ /// Indentation/wrapping
void _requireIndent(Count indentCount);
- void _appendWrappedIndented(Count indentCount, List<UnownedStringSlice>& slices, const UnownedStringSlice& delimit);
-
+ void _appendWrappedIndented(
+ Count indentCount,
+ List<UnownedStringSlice>& slices,
+ const UnownedStringSlice& delimit);
+
CommandOptions* m_commandOptions = nullptr;
- StringSlicePool m_pool;
+ StringSlicePool m_pool;
StringBuilder m_builder;
Options m_options;
};
} // namespace Slang
-#endif
+#endif
diff --git a/source/core/slang-command-options.cpp b/source/core/slang-command-options.cpp
index 5bbe59a0d..a4bb8b552 100644
--- a/source/core/slang-command-options.cpp
+++ b/source/core/slang-command-options.cpp
@@ -2,11 +2,12 @@
#include "slang-command-options.h"
-#include "slang-string-util.h"
-#include "slang-char-util.h"
#include "slang-byte-encode-util.h"
+#include "slang-char-util.h"
+#include "slang-string-util.h"
-namespace Slang {
+namespace Slang
+{
UnownedStringSlice CommandOptions::getFirstNameForOption(Index optionIndex)
{
@@ -26,7 +27,8 @@ CommandOptions::NameKey CommandOptions::getNameKeyForOption(Index optionIndex)
const auto& cat = m_categories[opt.categoryIndex];
NameKey key;
key.nameIndex = m_pool.findIndex(getFirstNameForOption(optionIndex));
- key.kind = (cat.kind == CategoryKind::Option) ? LookupKind::Option : makeLookupKind(opt.categoryIndex);
+ key.kind =
+ (cat.kind == CategoryKind::Option) ? LookupKind::Option : makeLookupKind(opt.categoryIndex);
return key;
}
@@ -38,7 +40,10 @@ CommandOptions::NameKey CommandOptions::getNameKeyForCategory(Index categoryInde
return key;
}
-SlangResult CommandOptions::_addName(LookupKind kind, const UnownedStringSlice& name, Index targetIndex)
+SlangResult CommandOptions::_addName(
+ LookupKind kind,
+ const UnownedStringSlice& name,
+ Index targetIndex)
{
NameKey nameKey;
nameKey.kind = kind;
@@ -52,7 +57,10 @@ SlangResult CommandOptions::_addName(LookupKind kind, const UnownedStringSlice&
return SLANG_OK;
}
-SlangResult CommandOptions::_addOptionName(const UnownedStringSlice& name, Flags flags, Index targetIndex)
+SlangResult CommandOptions::_addOptionName(
+ const UnownedStringSlice& name,
+ Flags flags,
+ Index targetIndex)
{
SLANG_RETURN_ON_FAIL(_addName(LookupKind::Option, name, targetIndex));
@@ -67,7 +75,10 @@ SlangResult CommandOptions::_addOptionName(const UnownedStringSlice& name, Flags
return SLANG_OK;
}
-SlangResult CommandOptions::_addValueName(const UnownedStringSlice& name, Index categoryIndex, Index optionIndex)
+SlangResult CommandOptions::_addValueName(
+ const UnownedStringSlice& name,
+ Index categoryIndex,
+ Index optionIndex)
{
return _addName(LookupKind(categoryIndex), name, optionIndex);
}
@@ -122,7 +133,10 @@ Index CommandOptions::_addOption(const UnownedStringSlice& name, const Option& i
}
}
-Index CommandOptions::_addOption(const UnownedStringSlice* names, Count namesCount, const Option& inOption)
+Index CommandOptions::_addOption(
+ const UnownedStringSlice* names,
+ Count namesCount,
+ const Option& inOption)
{
SLANG_ASSERT(namesCount > 0);
SLANG_ASSERT(inOption.categoryIndex >= 0);
@@ -134,7 +148,8 @@ Index CommandOptions::_addOption(const UnownedStringSlice* names, Count namesCou
auto& cat = m_categories[inOption.categoryIndex];
- // If there are already options associated with this category, we have to be in the run of the last ones added
+ // If there are already options associated with this category, we have to be in the run of the
+ // last ones added
if (cat.optionStartIndex != cat.optionEndIndex)
{
// If we aren't at the end then this is an error
@@ -172,9 +187,10 @@ Index CommandOptions::_addOption(const UnownedStringSlice* names, Count namesCou
{
for (Index i = 0; i < namesCount; ++i)
{
- _addValueName(names[i], inOption.categoryIndex, optionIndex);
+ _addValueName(names[i], inOption.categoryIndex, optionIndex);
}
- if (SLANG_FAILED(_addUserValue(LookupKind(inOption.categoryIndex), inOption.userValue, optionIndex)))
+ if (SLANG_FAILED(
+ _addUserValue(LookupKind(inOption.categoryIndex), inOption.userValue, optionIndex)))
{
return -1;
}
@@ -198,7 +214,7 @@ Index CommandOptions::_addOption(const UnownedStringSlice* names, Count namesCou
// Set the end index
cat.optionEndIndex = optionIndex + 1;
-
+
return optionIndex;
}
@@ -219,7 +235,11 @@ static void _handlePostFix(UnownedStringSlice& ioSlice, CommandOptions::Flags& i
}
}
-void CommandOptions::add(const char* inName, const char* usage, const char* description, UserValue userValue)
+void CommandOptions::add(
+ const char* inName,
+ const char* usage,
+ const char* description,
+ UserValue userValue)
{
UnownedStringSlice nameSlice(inName);
@@ -250,7 +270,13 @@ void CommandOptions::add(const char* inName, const char* usage, const char* desc
}
}
-void CommandOptions::add(const UnownedStringSlice* names, Count namesCount, const char* usage, const char* description, UserValue userValue, Flags flags)
+void CommandOptions::add(
+ const UnownedStringSlice* names,
+ Count namesCount,
+ const char* usage,
+ const char* description,
+ UserValue userValue,
+ Flags flags)
{
Option option;
option.categoryIndex = m_currentCategoryIndex;
@@ -337,7 +363,10 @@ void CommandOptions::addValue(const UnownedStringSlice& name, UserValue userValu
_addValue(name, option);
}
-void CommandOptions::addValue(const UnownedStringSlice& name, const UnownedStringSlice& description, UserValue userValue)
+void CommandOptions::addValue(
+ const UnownedStringSlice& name,
+ const UnownedStringSlice& description,
+ UserValue userValue)
{
Option option;
option.categoryIndex = m_currentCategoryIndex;
@@ -346,7 +375,10 @@ void CommandOptions::addValue(const UnownedStringSlice& name, const UnownedStrin
_addValue(name, option);
}
-void CommandOptions::addValue(const UnownedStringSlice* names, Count namesCount, UserValue userValue)
+void CommandOptions::addValue(
+ const UnownedStringSlice* names,
+ Count namesCount,
+ UserValue userValue)
{
Option option;
option.categoryIndex = m_currentCategoryIndex;
@@ -377,7 +409,11 @@ void CommandOptions::addValue(const char* name, UserValue userValue)
addValue(UnownedStringSlice(name), userValue);
}
-Index CommandOptions::addCategory(CategoryKind kind, const char* name, const char* description, UserValue userValue)
+Index CommandOptions::addCategory(
+ CategoryKind kind,
+ const char* name,
+ const char* description,
+ UserValue userValue)
{
const UnownedStringSlice nameSlice(name);
@@ -425,7 +461,10 @@ void CommandOptions::setCategory(const char* name)
m_currentCategoryIndex = -1;
}
-Index CommandOptions::findTargetIndexByName(LookupKind kind, const UnownedStringSlice& name, NameKey* outNameKey) const
+Index CommandOptions::findTargetIndexByName(
+ LookupKind kind,
+ const UnownedStringSlice& name,
+ NameKey* outNameKey) const
{
// Look up directly
{
@@ -470,7 +509,10 @@ Index CommandOptions::findTargetIndexByName(LookupKind kind, const UnownedString
return -1;
}
-Index CommandOptions::_findTargetIndexByName(LookupKind kind, const UnownedStringSlice& name, NameKey* outNameKey) const
+Index CommandOptions::_findTargetIndexByName(
+ LookupKind kind,
+ const UnownedStringSlice& name,
+ NameKey* outNameKey) const
{
const auto nameIndex = m_pool.findIndex(name);
// If the name isn't in the pool then there isn't a category with this name
@@ -524,7 +566,9 @@ Index CommandOptions::findCategoryByCaseInsensitiveName(const UnownedStringSlice
return -1;
}
-Index CommandOptions::findOptionByCategoryUserValue(UserValue categoryUserValue, const UnownedStringSlice& name) const
+Index CommandOptions::findOptionByCategoryUserValue(
+ UserValue categoryUserValue,
+ const UnownedStringSlice& name) const
{
Index categoryIndex = findTargetIndexByUserValue(LookupKind::Category, categoryUserValue);
if (categoryIndex < 0)
@@ -535,14 +579,19 @@ Index CommandOptions::findOptionByCategoryUserValue(UserValue categoryUserValue,
return findValueByName(categoryIndex, name);
}
-ConstArrayView<CommandOptions::Option> CommandOptions::getOptionsForCategory(Index categoryIndex) const
+ConstArrayView<CommandOptions::Option> CommandOptions::getOptionsForCategory(
+ Index categoryIndex) const
{
const auto& cat = m_categories[categoryIndex];
- return makeConstArrayView(m_options.getBuffer() + cat.optionStartIndex, cat.optionEndIndex - cat.optionStartIndex);
+ return makeConstArrayView(
+ m_options.getBuffer() + cat.optionStartIndex,
+ cat.optionEndIndex - cat.optionStartIndex);
}
-void CommandOptions::appendCategoryOptionNames(Index categoryIndex, List<UnownedStringSlice>& outNames) const
+void CommandOptions::appendCategoryOptionNames(
+ Index categoryIndex,
+ List<UnownedStringSlice>& outNames) const
{
for (const auto& option : getOptionsForCategory(categoryIndex))
{
@@ -550,28 +599,33 @@ void CommandOptions::appendCategoryOptionNames(Index categoryIndex, List<Unowned
}
}
-void CommandOptions::getCategoryOptionNames(Index categoryIndex, List<UnownedStringSlice>& outNames) const
+void CommandOptions::getCategoryOptionNames(Index categoryIndex, List<UnownedStringSlice>& outNames)
+ const
{
outNames.clear();
appendCategoryOptionNames(categoryIndex, outNames);
}
-void CommandOptions::splitUsage(const UnownedStringSlice& usageSlice, List<UnownedStringSlice>& outSlices) const
+void CommandOptions::splitUsage(
+ const UnownedStringSlice& usageSlice,
+ List<UnownedStringSlice>& outSlices) const
{
const auto* cur = usageSlice.begin();
const auto* end = usageSlice.end();
while (cur < end)
{
- // Find <
- while (cur < end && *cur != '<') cur++;
+ // Find <
+ while (cur < end && *cur != '<')
+ cur++;
// If we found it look for the end
if (cur < end && *cur == '<')
{
++cur;
auto start = cur;
- while (cur < end && (CharUtil::isAlphaOrDigit(*cur) || *cur == '-' || *cur == '_') && *cur != '>')
+ while (cur < end && (CharUtil::isAlphaOrDigit(*cur) || *cur == '-' || *cur == '_') &&
+ *cur != '>')
{
cur++;
}
@@ -594,7 +648,9 @@ void CommandOptions::splitUsage(const UnownedStringSlice& usageSlice, List<Unown
}
-void CommandOptions::findCategoryIndicesFromUsage(const UnownedStringSlice& slice, List<Index>& outCategories) const
+void CommandOptions::findCategoryIndicesFromUsage(
+ const UnownedStringSlice& slice,
+ List<Index>& outCategories) const
{
List<UnownedStringSlice> categoryNames;
splitUsage(slice, categoryNames);
@@ -609,7 +665,10 @@ void CommandOptions::findCategoryIndicesFromUsage(const UnownedStringSlice& slic
}
}
-Count CommandOptions::getOptionCountInRange(Index categoryIndex, UserValue start, UserValue nonInclEnd) const
+Count CommandOptions::getOptionCountInRange(
+ Index categoryIndex,
+ UserValue start,
+ UserValue nonInclEnd) const
{
const UserIndex startIndex = UserIndex(start);
const UserIndex endIndex = UserIndex(nonInclEnd);
@@ -631,7 +690,8 @@ Count CommandOptions::getOptionCountInRange(Index categoryIndex, UserValue start
return count;
}
-Count CommandOptions::getOptionCountInRange(LookupKind kind, UserValue start, UserValue nonInclEnd) const
+Count CommandOptions::getOptionCountInRange(LookupKind kind, UserValue start, UserValue nonInclEnd)
+ const
{
Index count = 0;
@@ -671,7 +731,10 @@ Count CommandOptions::getOptionCountInRange(LookupKind kind, UserValue start, Us
}
-bool CommandOptions::hasContiguousUserValueRange(LookupKind kind, UserValue start, UserValue nonInclEnd) const
+bool CommandOptions::hasContiguousUserValueRange(
+ LookupKind kind,
+ UserValue start,
+ UserValue nonInclEnd) const
{
const Count rangeCount = Count(nonInclEnd) - Count(start);
SLANG_ASSERT(rangeCount >= 0);
@@ -686,5 +749,3 @@ bool CommandOptions::hasContiguousUserValueRange(LookupKind kind, UserValue star
}
} // namespace Slang
-
-
diff --git a/source/core/slang-command-options.h b/source/core/slang-command-options.h
index 8b6d7b0ce..9d7af44d9 100644
--- a/source/core/slang-command-options.h
+++ b/source/core/slang-command-options.h
@@ -2,13 +2,13 @@
#define SLANG_CORE_COMMAND_OPTIONS_H
#include "slang-basic.h"
-#include "slang-string-slice-pool.h"
#include "slang-name-value.h"
+#include "slang-string-slice-pool.h"
namespace Slang
{
-/* For convenience we encode within "names" flags.
+/* For convenience we encode within "names" flags.
"-D..." means that -D *must* be followed by the value
"-D?..." means that -D *can* be a prefix, or it might be followed with the arg
*/
@@ -23,29 +23,36 @@ struct CommandOptions
enum class LookupKind : int32_t
{
- Category = -2, ///< Lookup a category name
- Option = -1, ///< Lookup an option name (all options use the same lookup index even if in different categories)
- Base = 0, ///< Lookup via category index
+ Category = -2, ///< Lookup a category name
+ Option = -1, ///< Lookup an option name (all options use the same lookup index even if in
+ ///< different categories)
+ Base = 0, ///< Lookup via category index
};
- /// A key type that uses the combination of the lookup kind and a name index.
- /// Maps to a target index that could be a category or an option index.
+ /// A key type that uses the combination of the lookup kind and a name index.
+ /// Maps to a target index that could be a category or an option index.
struct NameKey
{
typedef NameKey ThisType;
- SLANG_FORCE_INLINE bool operator==(const ThisType& rhs) const { return kind == rhs.kind && nameIndex == rhs.nameIndex; }
+ SLANG_FORCE_INLINE bool operator==(const ThisType& rhs) const
+ {
+ return kind == rhs.kind && nameIndex == rhs.nameIndex;
+ }
SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
- HashCode getHashCode() const { return combineHash(Slang::getHashCode(kind), Slang::getHashCode(nameIndex)); }
+ HashCode getHashCode() const
+ {
+ return combineHash(Slang::getHashCode(kind), Slang::getHashCode(nameIndex));
+ }
- LookupKind kind; ///< The kind of lookup
- Index nameIndex; ///< The name index in the pool
+ LookupKind kind; ///< The kind of lookup
+ Index nameIndex; ///< The name index in the pool
};
enum class CategoryKind
{
- Option, ///< Command line option (like "-D")
- Value, ///< One of a set of values (such as an enum or some other kind of list of values)
+ Option, ///< Command line option (like "-D")
+ Value, ///< One of a set of values (such as an enum or some other kind of list of values)
};
struct ValuePair
@@ -71,128 +78,179 @@ struct CommandOptions
{
enum Enum : Flags
{
- CanPrefix = 0x1, /// Allows -Dfsggf or -D fdsfsd
- IsPrefix = 0x2, /// Is an option that can only be a prefix
+ CanPrefix = 0x1, /// Allows -Dfsggf or -D fdsfsd
+ IsPrefix = 0x2, /// Is an option that can only be a prefix
};
};
struct Option
{
- UnownedStringSlice names; ///< Comma delimited list of names, first name is the default
- UnownedStringSlice usage; ///< Describes usage, can be empty
- UnownedStringSlice description; ///< A description of usage
+ UnownedStringSlice names; ///< Comma delimited list of names, first name is the default
+ UnownedStringSlice usage; ///< Describes usage, can be empty
+ UnownedStringSlice description; ///< A description of usage
UserValue userValue = kInvalidUserValue;
- Index categoryIndex = -1; ///< Category this option belongs to
- Flags flags = 0; ///< Flags about this option
+ Index categoryIndex = -1; ///< Category this option belongs to
+ Flags flags = 0; ///< Flags about this option
};
- /// Get the first name
+ /// Get the first name
UnownedStringSlice getFirstNameForOption(Index optionIndex);
- /// Get the first name for the category
+ /// Get the first name for the category
UnownedStringSlice getFirstNameForCategory(Index categoryIndex);
- /// Get a name key for an opton
+ /// Get a name key for an opton
NameKey getNameKeyForOption(Index optionIndex);
- /// Get a name key for a category
+ /// Get a name key for a category
NameKey getNameKeyForCategory(Index optionIndex);
- /// Add a category
- Index addCategory(CategoryKind kind, const char* name, const char* description, UserValue userValue = kInvalidUserValue);
- /// Use an already known category. It's an error if the category isn't found
+ /// Add a category
+ Index addCategory(
+ CategoryKind kind,
+ const char* name,
+ const char* description,
+ UserValue userValue = kInvalidUserValue);
+ /// Use an already known category. It's an error if the category isn't found
void setCategory(const char* name);
- void add(const char* name, const char* usage, const char* description, UserValue userValue = kInvalidUserValue);
- void add(const UnownedStringSlice* names, Count namesCount, const char* usage, const char* description, UserValue userValue = kInvalidUserValue, Flags flags = 0);
+ void add(
+ const char* name,
+ const char* usage,
+ const char* description,
+ UserValue userValue = kInvalidUserValue);
+ void add(
+ const UnownedStringSlice* names,
+ Count namesCount,
+ const char* usage,
+ const char* description,
+ UserValue userValue = kInvalidUserValue,
+ Flags flags = 0);
void addValue(const UnownedStringSlice& name, UserValue userValue = kInvalidUserValue);
- void addValue(const UnownedStringSlice& name, const UnownedStringSlice& description, UserValue userValue = kInvalidUserValue);
- void addValue(const char* name, const char* description, UserValue userValue = kInvalidUserValue);
+ void addValue(
+ const UnownedStringSlice& name,
+ const UnownedStringSlice& description,
+ UserValue userValue = kInvalidUserValue);
+ void addValue(
+ const char* name,
+ const char* description,
+ UserValue userValue = kInvalidUserValue);
void addValue(const char* name, UserValue userValue = kInvalidUserValue);
- void addValue(const UnownedStringSlice* names, Count namesCount, UserValue userValue = kInvalidUserValue);
+ void addValue(
+ const UnownedStringSlice* names,
+ Count namesCount,
+ UserValue userValue = kInvalidUserValue);
- /// Add values (without UserValue association)
+ /// Add values (without UserValue association)
void addValues(const ValuePair* pairs, Count pairsCount);
- /// Add values
+ /// Add values
void addValues(const ConstArrayView<NameValue>& values);
void addValues(const ConstArrayView<NamesValue>& values);
void addValues(const ConstArrayView<NamesDescriptionValue>& values);
- /// Sometimes values are listed with *names* per value. This method will take into account the aliases
+ /// Sometimes values are listed with *names* per value. This method will take into account the
+ /// aliases
void addValuesWithAliases(const ConstArrayView<NameValue>& values);
- /// Get the target index based off the name and the kind
- Index findTargetIndexByName(LookupKind kind, const UnownedStringSlice& name, NameKey* outNameKey = nullptr) const;
- /// Given a kind and a user value lookup the target index
+ /// Get the target index based off the name and the kind
+ Index findTargetIndexByName(
+ LookupKind kind,
+ const UnownedStringSlice& name,
+ NameKey* outNameKey = nullptr) const;
+ /// Given a kind and a user value lookup the target index
Index findTargetIndexByUserValue(LookupKind kind, UserValue userValue) const;
- /// Finds the category by name or -1 if not found
- Index findCategoryByName(const UnownedStringSlice& name) const { return findTargetIndexByName(LookupKind::Category, name); }
- /// Finds the option index by name or -1 if not found
- Index findOptionByName(const UnownedStringSlice& name) const { return findTargetIndexByName(LookupKind::Option, name); }
- /// Find the option index of a value, using it's category index and the name
- Index findValueByName(Index categoryIndex, const UnownedStringSlice& name) const { return findTargetIndexByName(LookupKind(categoryIndex), name); }
-
- /// Get the category index from a user value
- Index findCategoryByUserValue(UserValue userValue) const { return findTargetIndexByUserValue(LookupKind::Category, userValue); }
- /// Can only get options
- Index findOptionByUserValue(UserValue userValue) const { return findTargetIndexByUserValue(LookupKind::Option, userValue); }
- /// Get a value associated with a category
- Index findValueByUserValue(Index categoryIndex, UserValue userValue) const { return findTargetIndexByUserValue(LookupKind(categoryIndex), userValue); }
-
- /// Given a category user value, find the associated name
- /// Returns -1 if not found
- Index findOptionByCategoryUserValue(UserValue categoryUserValue, const UnownedStringSlice& name) const;
-
- /// Find a category by case insensitive name. Returns -1 if not found
+ /// Finds the category by name or -1 if not found
+ Index findCategoryByName(const UnownedStringSlice& name) const
+ {
+ return findTargetIndexByName(LookupKind::Category, name);
+ }
+ /// Finds the option index by name or -1 if not found
+ Index findOptionByName(const UnownedStringSlice& name) const
+ {
+ return findTargetIndexByName(LookupKind::Option, name);
+ }
+ /// Find the option index of a value, using it's category index and the name
+ Index findValueByName(Index categoryIndex, const UnownedStringSlice& name) const
+ {
+ return findTargetIndexByName(LookupKind(categoryIndex), name);
+ }
+
+ /// Get the category index from a user value
+ Index findCategoryByUserValue(UserValue userValue) const
+ {
+ return findTargetIndexByUserValue(LookupKind::Category, userValue);
+ }
+ /// Can only get options
+ Index findOptionByUserValue(UserValue userValue) const
+ {
+ return findTargetIndexByUserValue(LookupKind::Option, userValue);
+ }
+ /// Get a value associated with a category
+ Index findValueByUserValue(Index categoryIndex, UserValue userValue) const
+ {
+ return findTargetIndexByUserValue(LookupKind(categoryIndex), userValue);
+ }
+
+ /// Given a category user value, find the associated name
+ /// Returns -1 if not found
+ Index findOptionByCategoryUserValue(UserValue categoryUserValue, const UnownedStringSlice& name)
+ const;
+
+ /// Find a category by case insensitive name. Returns -1 if not found
Index findCategoryByCaseInsensitiveName(const UnownedStringSlice& slice) const;
-
- /// Given a category index returns all the options associated.
+
+ /// Given a category index returns all the options associated.
ConstArrayView<Option> getOptionsForCategory(Index categoryIndex) const;
- /// Get the categories
+ /// Get the categories
const List<Category>& getCategories() const { return m_categories; }
- /// Get all the options
+ /// Get all the options
const List<Option>& getOptions() const { return m_options; }
- /// Get the option at the specified index
+ /// Get the option at the specified index
const Option& getOptionAt(Index index) const { return m_options[index]; }
- /// Find all of the categories in the usage slice
- void findCategoryIndicesFromUsage(const UnownedStringSlice& usageSlice, List<Index>& outCategories) const;
+ /// Find all of the categories in the usage slice
+ void findCategoryIndicesFromUsage(
+ const UnownedStringSlice& usageSlice,
+ List<Index>& outCategories) const;
- /// Splits usage into category slices
- void splitUsage(const UnownedStringSlice& usageSlice, List<UnownedStringSlice>& outSlices) const;
+ /// Splits usage into category slices
+ void splitUsage(const UnownedStringSlice& usageSlice, List<UnownedStringSlice>& outSlices)
+ const;
- /// Get all the option names associated with a category index
+ /// Get all the option names associated with a category index
void getCategoryOptionNames(Index categoryIndex, List<UnownedStringSlice>& outNames) const;
void appendCategoryOptionNames(Index categoryIndex, List<UnownedStringSlice>& outNames) const;
- /// Set up a lookup kind from a category index
+ /// Set up a lookup kind from a category index
static LookupKind makeLookupKind(Index categoryIndex) { return LookupKind(categoryIndex); }
- /// Returns true, if all values from [start, end) are found for the kind
+ /// Returns true, if all values from [start, end) are found for the kind
bool hasContiguousUserValueRange(LookupKind kind, UserValue start, UserValue nonInclEnd) const;
- /// Returns the number of options in the range
+ /// Returns the number of options in the range
Count getOptionCountInRange(Index categoryIndex, UserValue start, UserValue nonInclEnd) const;
Count getOptionCountInRange(LookupKind kind, UserValue start, UserValue nonInclEnd) const;
/// Ctor
- CommandOptions() :
- m_pool(StringSlicePool::Style::Default),
- m_arena(1024 * 2)
+ CommandOptions()
+ : m_pool(StringSlicePool::Style::Default), m_arena(1024 * 2)
{
}
- protected:
- /// Returns name in the m_optionPool or -1 on error
+protected:
+ /// Returns name in the m_optionPool or -1 on error
SlangResult _addOptionName(const UnownedStringSlice& name, Flags flags, Index targetIndex);
- SlangResult _addValueName(const UnownedStringSlice& name, Index categoryIndex, Index targetIndex);
+ SlangResult _addValueName(
+ const UnownedStringSlice& name,
+ Index categoryIndex,
+ Index targetIndex);
SlangResult _addName(LookupKind kind, const UnownedStringSlice& name, Index targetIndex);
SlangResult _addUserValue(LookupKind kind, UserValue userValue, Index targetIndex);
@@ -205,18 +263,27 @@ struct CommandOptions
UnownedStringSlice _addString(const char* text);
UnownedStringSlice _addString(const UnownedStringSlice& slice);
- Index _findTargetIndexByName(LookupKind kind, const UnownedStringSlice& name, NameKey* outNameKey) const;
+ Index _findTargetIndexByName(
+ LookupKind kind,
+ const UnownedStringSlice& name,
+ NameKey* outNameKey) const;
struct UserValueKey
{
typedef UserValueKey ThisType;
- SLANG_FORCE_INLINE bool operator==(const ThisType& rhs) const { return kind == rhs.kind && userValue == rhs.userValue; }
+ SLANG_FORCE_INLINE bool operator==(const ThisType& rhs) const
+ {
+ return kind == rhs.kind && userValue == rhs.userValue;
+ }
SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
- HashCode getHashCode() const { return combineHash(Slang::getHashCode(kind), Slang::getHashCode(userValue)); }
+ HashCode getHashCode() const
+ {
+ return combineHash(Slang::getHashCode(kind), Slang::getHashCode(userValue));
+ }
- LookupKind kind; ///< The kind of lookup
- UserValue userValue; ///< The user value
+ LookupKind kind; ///< The kind of lookup
+ UserValue userValue; ///< The user value
};
Index m_currentCategoryIndex = -1;
@@ -226,14 +293,14 @@ struct CommandOptions
// Holds a bit for all valid prefix sizes. Max prefix size is therefore 32 chars
uint32_t m_prefixSizes = 0;
- List<Option> m_options; ///< All of the entries describing each of the options
- StringSlicePool m_pool; ///< Only holds options, and handle therefore matches up to m_entries
+ List<Option> m_options; ///< All of the entries describing each of the options
+ StringSlicePool m_pool; ///< Only holds options, and handle therefore matches up to m_entries
Dictionary<NameKey, Index> m_nameMap; ///< Maps a name to an option index
Dictionary<UserValueKey, Index> m_userValueMap; ///< Maps a user value (for a kind) to an index
- MemoryArena m_arena; ///< For other misc storage
+ MemoryArena m_arena; ///< For other misc storage
};
} // namespace Slang
-#endif
+#endif
diff --git a/source/core/slang-common.h b/source/core/slang-common.h
index 2952eccd2..2aec6f0ce 100644
--- a/source/core/slang-common.h
+++ b/source/core/slang-common.h
@@ -1,106 +1,107 @@
#pragma once
+#include "slang-signal.h"
#include "slang.h"
#include <assert.h>
-
#include <stdint.h>
-#include "slang-signal.h"
-
#define VARIADIC_TEMPLATE
namespace Slang
{
-
- typedef int32_t Int32;
- typedef uint32_t UInt32;
- typedef int64_t Int64;
- typedef uint64_t UInt64;
+typedef int32_t Int32;
+typedef uint32_t UInt32;
+
+typedef int64_t Int64;
+typedef uint64_t UInt64;
- // Define
- typedef SlangUInt UInt;
- typedef SlangInt Int;
+// Define
+typedef SlangUInt UInt;
+typedef SlangInt Int;
- static const UInt kMaxUInt = ~UInt(0);
- static const Int kMaxInt = Int(kMaxUInt >> 1);
+static const UInt kMaxUInt = ~UInt(0);
+static const Int kMaxInt = Int(kMaxUInt >> 1);
// typedef unsigned short Word;
- typedef intptr_t PtrInt;
+typedef intptr_t PtrInt;
- // TODO(JS): It looks like Index is actually 64 bit on 64 bit targets(!)
- // Previous discussions landed on Index being int32_t.
+// TODO(JS): It looks like Index is actually 64 bit on 64 bit targets(!)
+// Previous discussions landed on Index being int32_t.
- // Type used for indexing, in arrays/views etc. Signed.
- typedef Int Index;
- typedef UInt UIndex;
- typedef Int Count;
- typedef UInt UCount;
+// Type used for indexing, in arrays/views etc. Signed.
+typedef Int Index;
+typedef UInt UIndex;
+typedef Int Count;
+typedef UInt UCount;
- static const Index kMaxIndex = kMaxInt;
+static const Index kMaxIndex = kMaxInt;
- typedef uint8_t Byte;
+typedef uint8_t Byte;
- // TODO(JS):
- // Perhaps these should be named Utf8, Utf16 and UnicodePoint/Rune/etc? For now, just keep it simple
- //
- typedef char Char8;
- // 16 bit character. Note much like in utf8, a character may or may not represent a code point (it can be part of a code point).
- typedef uint16_t Char16;
+// TODO(JS):
+// Perhaps these should be named Utf8, Utf16 and UnicodePoint/Rune/etc? For now, just keep it simple
+//
+typedef char Char8;
+// 16 bit character. Note much like in utf8, a character may or may not represent a code point (it
+// can be part of a code point).
+typedef uint16_t Char16;
- // Can always hold a unicode code point.
- typedef uint32_t Char32;
+// Can always hold a unicode code point.
+typedef uint32_t Char32;
- template <typename T>
- inline T&& _Move(T & obj)
- {
- return static_cast<T&&>(obj);
- }
+template<typename T>
+inline T&& _Move(T& obj)
+{
+ return static_cast<T&&>(obj);
+}
- template <typename T>
- inline void Swap(T & v0, T & v1)
- {
- T tmp = _Move(v0);
- v0 = _Move(v1);
- v1 = _Move(tmp);
- }
+template<typename T>
+inline void Swap(T& v0, T& v1)
+{
+ T tmp = _Move(v0);
+ v0 = _Move(v1);
+ v1 = _Move(tmp);
+}
- // Make these interfaces have more convenient names
- typedef ISlangCastable ICastable;
- typedef ISlangClonable IClonable;
+// Make these interfaces have more convenient names
+typedef ISlangCastable ICastable;
+typedef ISlangClonable IClonable;
- // Convenience function for using clonable
- template <typename T>
- SLANG_FORCE_INLINE T* clone(IClonable* clonable) { return (T*)clonable->clone(T::getTypeGuid()); }
+// Convenience function for using clonable
+template<typename T>
+SLANG_FORCE_INLINE T* clone(IClonable* clonable)
+{
+ return (T*)clonable->clone(T::getTypeGuid());
+}
- template <typename T>
- inline bool isBitSet(T value, T bitToTest)
- {
- static_assert(sizeof(T) <= sizeof(uint32_t), "Only support up to 32 bit enums");
- return (T)((uint32_t)value & (uint32_t)bitToTest) == bitToTest;
- }
+template<typename T>
+inline bool isBitSet(T value, T bitToTest)
+{
+ static_assert(sizeof(T) <= sizeof(uint32_t), "Only support up to 32 bit enums");
+ return (T)((uint32_t)value & (uint32_t)bitToTest) == bitToTest;
}
+} // namespace Slang
// SLANG_DEFER
template<typename F>
class SlangDeferImpl
{
F f;
+
public:
SlangDeferImpl(F&& f)
: f(Slang::_Move(f))
- {}
- ~SlangDeferImpl()
{
- f();
}
+ ~SlangDeferImpl() { f(); }
};
#ifndef SLANG_DEFER_LAMBDA
#define SLANG_DEFER_LAMBDA(x) auto SLANG_CONCAT(slang_defer_, __LINE__) = SlangDeferImpl(x)
-#define SLANG_DEFER(x) auto SLANG_CONCAT(slang_defer_,__LINE__) = SlangDeferImpl([&](){x;})
+#define SLANG_DEFER(x) auto SLANG_CONCAT(slang_defer_, __LINE__) = SlangDeferImpl([&]() { x; })
#endif
//
@@ -115,38 +116,38 @@ public:
#else
#define SLANG_COMPONENTWISE_EQUALITY_1(type) \
bool operator==(const type& other) const \
- { \
- const auto& [m1] = *this; \
- const auto& [o1] = other; \
- return m1 == o1; \
- } \
+ { \
+ const auto& [m1] = *this; \
+ const auto& [o1] = other; \
+ return m1 == o1; \
+ } \
bool operator!=(const type& other) const \
- { \
- return !(*this == other); \
+ { \
+ return !(*this == other); \
}
#define SLANG_COMPONENTWISE_EQUALITY_2(type) \
bool operator==(const type& other) const \
- { \
- const auto& [m1, m2] = *this; \
- const auto& [o1, o2] = other; \
- return m1 == o1 && m2 == o2; \
- } \
+ { \
+ const auto& [m1, m2] = *this; \
+ const auto& [o1, o2] = other; \
+ return m1 == o1 && m2 == o2; \
+ } \
bool operator!=(const type& other) const \
- { \
- return !(*this == other); \
+ { \
+ return !(*this == other); \
}
-#define SLANG_COMPONENTWISE_EQUALITY_3(type) \
- bool operator==(const type& other) const \
- { \
- const auto& [m1, m2, m3] = *this; \
- const auto& [o1, o2, o3] = other; \
+#define SLANG_COMPONENTWISE_EQUALITY_3(type) \
+ bool operator==(const type& other) const \
+ { \
+ const auto& [m1, m2, m3] = *this; \
+ const auto& [o1, o2, o3] = other; \
return m1 == o1 && m2 == o2 && m3 == o3; \
- } \
- bool operator!=(const type& other) const \
- { \
- return !(*this == other); \
+ } \
+ bool operator!=(const type& other) const \
+ { \
+ return !(*this == other); \
}
#endif
@@ -158,49 +159,43 @@ public:
#endif
#if SLANG_GCC
-# define SLANG_EXHAUSTIVE_SWITCH_BEGIN \
- _Pragma("GCC diagnostic push"); \
- _Pragma("GCC diagnostic error \"-Wswitch-enum\"");
-# define SLANG_EXHAUSTIVE_SWITCH_END \
- _Pragma("GCC diagnostic pop");
+#define SLANG_EXHAUSTIVE_SWITCH_BEGIN \
+ _Pragma("GCC diagnostic push"); \
+ _Pragma("GCC diagnostic error \"-Wswitch-enum\"");
+#define SLANG_EXHAUSTIVE_SWITCH_END _Pragma("GCC diagnostic pop");
#elif SLANG_CLANG
-# define SLANG_EXHAUSTIVE_SWITCH_BEGIN \
- _Pragma("clang diagnostic push"); \
- _Pragma("clang diagnostic error \"-Wswitch-enum\"");
-# define SLANG_EXHAUSTIVE_SWITCH_END \
- _Pragma("clang diagnostic pop");
+#define SLANG_EXHAUSTIVE_SWITCH_BEGIN \
+ _Pragma("clang diagnostic push"); \
+ _Pragma("clang diagnostic error \"-Wswitch-enum\"");
+#define SLANG_EXHAUSTIVE_SWITCH_END _Pragma("clang diagnostic pop");
#elif SLANG_VC
-# define SLANG_EXHAUSTIVE_SWITCH_BEGIN \
- _Pragma("warning(push)"); \
- _Pragma("warning(error : 4062)");
-# define SLANG_EXHAUSTIVE_SWITCH_END \
- _Pragma("warning(pop)");
+#define SLANG_EXHAUSTIVE_SWITCH_BEGIN \
+ _Pragma("warning(push)"); \
+ _Pragma("warning(error : 4062)");
+#define SLANG_EXHAUSTIVE_SWITCH_END _Pragma("warning(pop)");
#else
-# define SLANG_EXHAUSTIVE_SWITCH_BEGIN
-# define SLANG_EXHAUSTIVE_SWITCH_END
+#define SLANG_EXHAUSTIVE_SWITCH_BEGIN
+#define SLANG_EXHAUSTIVE_SWITCH_END
#endif
#if SLANG_GCC
-# define SLANG_ALLOW_DEPRECATED_BEGIN \
- _Pragma("GCC diagnostic push"); \
- _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"");
-# define SLANG_ALLOW_DEPRECATED_END \
- _Pragma("GCC diagnostic pop");
+#define SLANG_ALLOW_DEPRECATED_BEGIN \
+ _Pragma("GCC diagnostic push"); \
+ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"");
+#define SLANG_ALLOW_DEPRECATED_END _Pragma("GCC diagnostic pop");
#elif SLANG_CLANG
-# define SLANG_ALLOW_DEPRECATED_BEGIN \
- _Pragma("clang diagnostic push"); \
- _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"");
-# define SLANG_ALLOW_DEPRECATED_END \
- _Pragma("clang diagnostic pop");
+#define SLANG_ALLOW_DEPRECATED_BEGIN \
+ _Pragma("clang diagnostic push"); \
+ _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"");
+#define SLANG_ALLOW_DEPRECATED_END _Pragma("clang diagnostic pop");
#elif SLANG_VC
-# define SLANG_ALLOW_DEPRECATED_BEGIN \
- _Pragma("warning(push)"); \
- _Pragma("warning(disable : 4996)");
-# define SLANG_ALLOW_DEPRECATED_END \
- _Pragma("warning(pop)");
+#define SLANG_ALLOW_DEPRECATED_BEGIN \
+ _Pragma("warning(push)"); \
+ _Pragma("warning(disable : 4996)");
+#define SLANG_ALLOW_DEPRECATED_END _Pragma("warning(pop)");
#else
-# define SLANG_ALLOW_DEPRECATED_BEGIN
-# define SLANG_ALLOW_DEPRECATED_END
+#define SLANG_ALLOW_DEPRECATED_BEGIN
+#define SLANG_ALLOW_DEPRECATED_END
#endif
//
@@ -208,16 +203,26 @@ public:
// Do not rely on side effects of the condition being performed.
//
#if defined(__cpp_assume)
-# define SLANG_ASSUME(X) [[assume(X)]]
+#define SLANG_ASSUME(X) [[assume(X)]]
#elif SLANG_GCC
-# define SLANG_ASSUME(X) do{if(!(X)) __builtin_unreachable();} while(0)
+#define SLANG_ASSUME(X) \
+ do \
+ { \
+ if (!(X)) \
+ __builtin_unreachable(); \
+ } while (0)
#elif SLANG_CLANG
-# define SLANG_ASSUME(X) __builtin_assume(X)
+#define SLANG_ASSUME(X) __builtin_assume(X)
#elif SLANG_VC
-# define SLANG_ASSUME(X) __assume(X)
+#define SLANG_ASSUME(X) __assume(X)
#else
- [[noreturn]] inline void invokeUndefinedBehaviour() {}
-# define SLANG_ASSUME(X) do{if(!(X)) invokeUndefinedBehaviour();} while(0)
+[[noreturn]] inline void invokeUndefinedBehaviour() {}
+#define SLANG_ASSUME(X) \
+ do \
+ { \
+ if (!(X)) \
+ invokeUndefinedBehaviour(); \
+ } while (0)
#endif
//
@@ -225,37 +230,51 @@ public:
// assumptions in release builds
//
#ifdef _DEBUG
-#define SLANG_ASSERT(VALUE) do{if(!(VALUE)) SLANG_ASSERT_FAILURE(#VALUE);} while(0)
+#define SLANG_ASSERT(VALUE) \
+ do \
+ { \
+ if (!(VALUE)) \
+ SLANG_ASSERT_FAILURE(#VALUE); \
+ } while (0)
#else
#define SLANG_ASSERT(VALUE) SLANG_ASSUME(VALUE)
#endif
-#define SLANG_RELEASE_ASSERT(VALUE) if(VALUE) {} else SLANG_ASSERT_FAILURE(#VALUE)
+#define SLANG_RELEASE_ASSERT(VALUE) \
+ if (VALUE) \
+ { \
+ } \
+ else \
+ SLANG_ASSERT_FAILURE(#VALUE)
-template<typename T> void slang_use_obj(T&) {}
+template<typename T>
+void slang_use_obj(T&)
+{
+}
#define SLANG_UNREFERENCED_PARAMETER(P) slang_use_obj(P)
#define SLANG_UNREFERENCED_VARIABLE(P) slang_use_obj(P)
#if defined(SLANG_RT_DYNAMIC)
#if defined(_MSC_VER)
-# ifdef SLANG_RT_DYNAMIC_EXPORT
-# define SLANG_RT_API SLANG_DLL_EXPORT
-# else
-# define SLANG_RT_API __declspec(dllimport)
-# endif
+#ifdef SLANG_RT_DYNAMIC_EXPORT
+#define SLANG_RT_API SLANG_DLL_EXPORT
+#else
+#define SLANG_RT_API __declspec(dllimport)
+#endif
#else
// TODO: need to consider compiler capabilities
-//# ifdef SLANG_RT_DYNAMIC_EXPORT
-# define SLANG_RT_API SLANG_DLL_EXPORT
-//# endif
+// # ifdef SLANG_RT_DYNAMIC_EXPORT
+#define SLANG_RT_API SLANG_DLL_EXPORT
+// # endif
#endif
#endif
#if defined(_MSC_VER)
-# define SLANG_ATTR_PRINTF(string_index, varargs_index)
+#define SLANG_ATTR_PRINTF(string_index, varargs_index)
#else
-# define SLANG_ATTR_PRINTF(string_index, varargs_index) __attribute__((format(printf, string_index, varargs_index)))
+#define SLANG_ATTR_PRINTF(string_index, varargs_index) \
+ __attribute__((format(printf, string_index, varargs_index)))
#endif
#ifndef SLANG_RT_API
diff --git a/source/core/slang-compression-system.h b/source/core/slang-compression-system.h
index ecc5b1be9..806228f64 100644
--- a/source/core/slang-compression-system.h
+++ b/source/core/slang-compression-system.h
@@ -10,13 +10,14 @@ struct CompressionStyle
{
enum class Type
{
- Level, ///< Use the value specified in 'level' to control compression
- BestSpeed, ///< Best for speed (typically lower compression ration)
- BestCompression, ///< Best compression (typically slower)
- Default, ///< Default compression (a good balance between speed and size)
+ Level, ///< Use the value specified in 'level' to control compression
+ BestSpeed, ///< Best for speed (typically lower compression ration)
+ BestCompression, ///< Best compression (typically slower)
+ Default, ///< Default compression (a good balance between speed and size)
};
- Type m_type = Type::Default; ///< The type
- float m_level = 1.0f; ///< 0 lowest compression, 1 highest compression (Ignored if m_type != Type::Level)
+ Type m_type = Type::Default; ///< The type
+ float m_level =
+ 1.0f; ///< 0 lowest compression, 1 highest compression (Ignored if m_type != Type::Level)
};
enum class CompressionSystemType
@@ -29,28 +30,41 @@ enum class CompressionSystemType
class ICompressionSystem : public ISlangUnknown
{
- SLANG_COM_INTERFACE(0xcc935840, 0xe059, 0x4bb8, { 0xa2, 0x2d, 0x92, 0x7b, 0x3c, 0x73, 0x8f, 0x85 })
+ SLANG_COM_INTERFACE(
+ 0xcc935840,
+ 0xe059,
+ 0x4bb8,
+ {0xa2, 0x2d, 0x92, 0x7b, 0x3c, 0x73, 0x8f, 0x85})
- /** Get the compression system type
- @return The compression system type */
+ /** Get the compression system type
+ @return The compression system type */
virtual SLANG_NO_THROW CompressionSystemType SLANG_MCALL getSystemType() = 0;
- /** compress
- @param src Points to the start of the data to compress
- @param srcSizeInBytes The size of the source data to compress in bytes
- @param outBlob The input data compressed
- @return SLANG_OK if successful */
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compress(const CompressionStyle* style, const void* src, size_t srcSizeInBytes, ISlangBlob** outBlob) = 0;
-
- /* decompress
- @param compressed The start of the compressed data
- @param compressedSizeInBytes The compressed size in bytes
- @param decompressedSizeInBytes The size of the decompressed buffer. MUST be exactly the same as the original source size.
- @param outDecompressed Where decompressed data is written
- @return SLANG_OK if successful */
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL decompress(const void* compressed, size_t compressedSizeInBytes, size_t decompressedSizeInBytes, void* outDecompressed) = 0;
+ /** compress
+ @param src Points to the start of the data to compress
+ @param srcSizeInBytes The size of the source data to compress in bytes
+ @param outBlob The input data compressed
+ @return SLANG_OK if successful */
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compress(
+ const CompressionStyle* style,
+ const void* src,
+ size_t srcSizeInBytes,
+ ISlangBlob** outBlob) = 0;
+
+ /* decompress
+ @param compressed The start of the compressed data
+ @param compressedSizeInBytes The compressed size in bytes
+ @param decompressedSizeInBytes The size of the decompressed buffer. MUST be exactly the same as
+ the original source size.
+ @param outDecompressed Where decompressed data is written
+ @return SLANG_OK if successful */
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL decompress(
+ const void* compressed,
+ size_t compressedSizeInBytes,
+ size_t decompressedSizeInBytes,
+ void* outDecompressed) = 0;
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-crypto.cpp b/source/core/slang-crypto.cpp
index 138454140..49371eaea 100644
--- a/source/core/slang-crypto.cpp
+++ b/source/core/slang-crypto.cpp
@@ -2,13 +2,14 @@
* MD5 implementation is based on:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
* Original file header is at the bottom of this file.
- *
+ *
* SHA1 implementation is based on:
* https://github.com/983/SHA1
* Original LICENSE is at the bottom of this file.
*/
#include "slang-crypto.h"
+
#include "../core/slang-char-util.h"
namespace Slang
@@ -32,7 +33,11 @@ namespace Slang
return str;
}
-/*static*/ bool DigestUtil::stringToDigest(const char* str, SlangInt strLength, void *digest, SlangInt digestSize)
+/*static*/ bool DigestUtil::stringToDigest(
+ const char* str,
+ SlangInt strLength,
+ void* digest,
+ SlangInt digestSize)
{
SLANG_ASSERT(str && strLength >= 0 && digest && digestSize >= 0);
@@ -52,7 +57,8 @@ namespace Slang
::memset(digest, 0, digestSize);
return false;
}
- data[i] = uint8_t(lower | upper << 4);;
+ data[i] = uint8_t(lower | upper << 4);
+ ;
}
return true;
@@ -164,17 +170,17 @@ MD5::Digest MD5::finalize()
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
* implementation.
*/
-#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
-#define H(x, y, z) (((x) ^ (y)) ^ (z))
-#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z) (((x) ^ (y)) ^ (z))
+#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
/*
* The MD5 transformation for all four rounds.
*/
-#define STEP(f, a, b, c, d, x, t, s) \
- (a) += f((b), (c), (d)) + (x) + (t); \
+#define STEP(f, a, b, c, d, x, t, s) \
+ (a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b);
@@ -182,14 +188,10 @@ MD5::Digest MD5::finalize()
* SET reads 4 input bytes in little-endian byte order and stores them in a
* properly aligned word in host byte order.
*/
-#define SET(n) \
- (m_block[(n)] = \
- (uint32_t)ptr[(n) * 4] | \
- ((uint32_t)ptr[(n) * 4 + 1] << 8) | \
- ((uint32_t)ptr[(n) * 4 + 2] << 16) | \
- ((uint32_t)ptr[(n) * 4 + 3] << 24))
-#define GET(n) \
- (m_block[(n)])
+#define SET(n) \
+ (m_block[(n)] = (uint32_t)ptr[(n) * 4] | ((uint32_t)ptr[(n) * 4 + 1] << 8) | \
+ ((uint32_t)ptr[(n) * 4 + 2] << 16) | ((uint32_t)ptr[(n) * 4 + 3] << 24))
+#define GET(n) (m_block[(n)])
const void* MD5::processBlock(const void* data, SlangInt size)
{
@@ -286,8 +288,7 @@ const void* MD5::processBlock(const void* data, SlangInt size)
d += saved_d;
ptr += 64;
- }
- while (size -= 64);
+ } while (size -= 64);
m_a = a;
m_b = b;
@@ -405,14 +406,12 @@ void SHA1::addByte(uint8_t byte)
void SHA1::processBlock(const uint8_t* ptr)
{
- auto rol32 = [](uint32_t x, uint32_t n)
- {
- return (x << n) | (x >> (32 - n));
- };
+ auto rol32 = [](uint32_t x, uint32_t n) { return (x << n) | (x >> (32 - n)); };
auto makeWord = [](const uint8_t* p)
{
- return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
+ return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) |
+ (uint32_t)p[3];
};
const uint32_t c0 = 0x5a827999;
@@ -433,23 +432,34 @@ void SHA1::processBlock(const uint8_t* ptr)
w[i] = makeWord(ptr + i * 4);
}
-#define SHA1_LOAD(i) w[i&15] = rol32(w[(i + 13) & 15] ^ w[(i + 8) & 15] ^ w[(i + 2) & 15] ^ w[i & 15], 1);
-#define SHA1_ROUND_0(v,u,x,y,z,i) z += ((u & (x ^ y)) ^ y) + w[i & 15] + c0 + rol32(v, 5); u = rol32(u, 30);
-#define SHA1_ROUND_1(v,u,x,y,z,i) SHA1_LOAD(i) z += ((u & (x ^ y)) ^ y) + w[i & 15] + c0 + rol32(v, 5); u = rol32(u, 30);
-#define SHA1_ROUND_2(v,u,x,y,z,i) SHA1_LOAD(i) z += (u ^ x ^ y) + w[i & 15] + c1 + rol32(v, 5); u = rol32(u, 30);
-#define SHA1_ROUND_3(v,u,x,y,z,i) SHA1_LOAD(i) z += (((u | x) & y) | (u & x)) + w[i & 15] + c2 + rol32(v, 5); u = rol32(u, 30);
-#define SHA1_ROUND_4(v,u,x,y,z,i) SHA1_LOAD(i) z += (u ^ x ^ y) + w[i & 15] + c3 + rol32(v, 5); u = rol32(u, 30);
-
- SHA1_ROUND_0(a, b, c, d, e, 0);
- SHA1_ROUND_0(e, a, b, c, d, 1);
- SHA1_ROUND_0(d, e, a, b, c, 2);
- SHA1_ROUND_0(c, d, e, a, b, 3);
- SHA1_ROUND_0(b, c, d, e, a, 4);
- SHA1_ROUND_0(a, b, c, d, e, 5);
- SHA1_ROUND_0(e, a, b, c, d, 6);
- SHA1_ROUND_0(d, e, a, b, c, 7);
- SHA1_ROUND_0(c, d, e, a, b, 8);
- SHA1_ROUND_0(b, c, d, e, a, 9);
+#define SHA1_LOAD(i) \
+ w[i & 15] = rol32(w[(i + 13) & 15] ^ w[(i + 8) & 15] ^ w[(i + 2) & 15] ^ w[i & 15], 1);
+#define SHA1_ROUND_0(v, u, x, y, z, i) \
+ z += ((u & (x ^ y)) ^ y) + w[i & 15] + c0 + rol32(v, 5); \
+ u = rol32(u, 30);
+#define SHA1_ROUND_1(v, u, x, y, z, i) \
+ SHA1_LOAD(i) z += ((u & (x ^ y)) ^ y) + w[i & 15] + c0 + rol32(v, 5); \
+ u = rol32(u, 30);
+#define SHA1_ROUND_2(v, u, x, y, z, i) \
+ SHA1_LOAD(i) z += (u ^ x ^ y) + w[i & 15] + c1 + rol32(v, 5); \
+ u = rol32(u, 30);
+#define SHA1_ROUND_3(v, u, x, y, z, i) \
+ SHA1_LOAD(i) z += (((u | x) & y) | (u & x)) + w[i & 15] + c2 + rol32(v, 5); \
+ u = rol32(u, 30);
+#define SHA1_ROUND_4(v, u, x, y, z, i) \
+ SHA1_LOAD(i) z += (u ^ x ^ y) + w[i & 15] + c3 + rol32(v, 5); \
+ u = rol32(u, 30);
+
+ SHA1_ROUND_0(a, b, c, d, e, 0);
+ SHA1_ROUND_0(e, a, b, c, d, 1);
+ SHA1_ROUND_0(d, e, a, b, c, 2);
+ SHA1_ROUND_0(c, d, e, a, b, 3);
+ SHA1_ROUND_0(b, c, d, e, a, 4);
+ SHA1_ROUND_0(a, b, c, d, e, 5);
+ SHA1_ROUND_0(e, a, b, c, d, 6);
+ SHA1_ROUND_0(d, e, a, b, c, 7);
+ SHA1_ROUND_0(c, d, e, a, b, 8);
+ SHA1_ROUND_0(b, c, d, e, a, 9);
SHA1_ROUND_0(a, b, c, d, e, 10);
SHA1_ROUND_0(e, a, b, c, d, 11);
SHA1_ROUND_0(d, e, a, b, c, 12);
@@ -535,14 +545,14 @@ void SHA1::processBlock(const uint8_t* ptr)
m_state[4] += e;
}
-/* static */SHA1::Digest SHA1::compute(const void* data, SlangInt size)
+/* static */ SHA1::Digest SHA1::compute(const void* data, SlangInt size)
{
SHA1 sha1;
sha1.update(data, size);
return sha1.finalize();
}
-}
+} // namespace Slang
/*
@@ -584,12 +594,12 @@ void SHA1::processBlock(const uint8_t* ptr)
/*
* This is free and unencumbered software released into the public domain.
- *
+ *
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
- *
+ *
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
@@ -597,7 +607,7 @@ void SHA1::processBlock(const uint8_t* ptr)
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -605,6 +615,6 @@ void SHA1::processBlock(const uint8_t* ptr)
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
* For more information, please refer to <http://unlicense.org>
*/
diff --git a/source/core/slang-crypto.h b/source/core/slang-crypto.h
index feab88aa4..325130a85 100644
--- a/source/core/slang-crypto.h
+++ b/source/core/slang-crypto.h
@@ -1,184 +1,158 @@
#pragma once
-#include "slang.h"
-#include "../core/slang-string.h"
#include "../core/slang-blob.h"
#include "../core/slang-list.h"
+#include "../core/slang-string.h"
+#include "slang.h"
namespace Slang
{
- struct DigestUtil
- {
- /// Convert a binary digest to a string (lower-case hexadecimal).
- /// Returned string is double the length of the digest.
- static String digestToString(const void* digest, SlangInt digestSize);
-
- /// Convert a string to a binary digest.
- /// Expects a string of double the length of the digest size in hexadecimal format.
- /// Sets the digest to all zeros if the string is invalid.
- /// Returns true if string was converted successfully.
- static bool stringToDigest(const char* str, SlangInt strLength, void *digest, SlangInt digestSize);
- };
-
- /// Represents a hash digest. Only sizes of multiple of 4 are supported.
- template<SlangInt N>
- class HashDigest
- {
- public:
- static_assert(N % 4 == 0, "size must be multiple of 4");
- uint32_t data[N / 4] = { 0 };
+struct DigestUtil
+{
+ /// Convert a binary digest to a string (lower-case hexadecimal).
+ /// Returned string is double the length of the digest.
+ static String digestToString(const void* digest, SlangInt digestSize);
+
+ /// Convert a string to a binary digest.
+ /// Expects a string of double the length of the digest size in hexadecimal format.
+ /// Sets the digest to all zeros if the string is invalid.
+ /// Returns true if string was converted successfully.
+ static bool stringToDigest(
+ const char* str,
+ SlangInt strLength,
+ void* digest,
+ SlangInt digestSize);
+};
+
+/// Represents a hash digest. Only sizes of multiple of 4 are supported.
+template<SlangInt N>
+class HashDigest
+{
+public:
+ static_assert(N % 4 == 0, "size must be multiple of 4");
+ uint32_t data[N / 4] = {0};
- HashDigest() = default;
+ HashDigest() = default;
- HashDigest(const char* str)
- {
- DigestUtil::stringToDigest(str, ::strlen(str), data, N);
- }
+ HashDigest(const char* str) { DigestUtil::stringToDigest(str, ::strlen(str), data, N); }
- HashDigest(const String& str)
- {
- DigestUtil::stringToDigest(str.getBuffer(), str.getLength(), data, N);
- }
+ HashDigest(const String& str)
+ {
+ DigestUtil::stringToDigest(str.getBuffer(), str.getLength(), data, N);
+ }
- HashDigest(const UnownedStringSlice& str)
- {
- DigestUtil::stringToDigest(str.begin(), str.getLength(), data, N);
- }
+ HashDigest(const UnownedStringSlice& str)
+ {
+ DigestUtil::stringToDigest(str.begin(), str.getLength(), data, N);
+ }
- HashDigest(ISlangBlob* blob)
+ HashDigest(ISlangBlob* blob)
+ {
+ if (blob->getBufferSize() == N)
{
- if (blob->getBufferSize() == N)
- {
- ::memcpy(data, blob->getBufferPointer(), N);
- }
+ ::memcpy(data, blob->getBufferPointer(), N);
}
+ }
- String toString() const
- {
- return DigestUtil::digestToString(data, N);
- }
+ String toString() const { return DigestUtil::digestToString(data, N); }
- ComPtr<ISlangBlob> toBlob() const
- {
- return RawBlob::create(data, sizeof(data));
- }
+ ComPtr<ISlangBlob> toBlob() const { return RawBlob::create(data, sizeof(data)); }
- bool operator==(const HashDigest& other) const
- {
- return ::memcmp(data, other.data, sizeof(data)) == 0;
- }
+ bool operator==(const HashDigest& other) const
+ {
+ return ::memcmp(data, other.data, sizeof(data)) == 0;
+ }
- bool operator!=(const HashDigest& other) const
- {
- return !(*this == other);
- }
+ bool operator!=(const HashDigest& other) const { return !(*this == other); }
- uint32_t getHashCode() const
- {
- return data[0];
- }
- };
+ uint32_t getHashCode() const { return data[0]; }
+};
- /// MD5 hash generator implementing https://www.ietf.org/rfc/rfc1321.txt
- class MD5
- {
- public:
- using Digest = HashDigest<16>;
+/// MD5 hash generator implementing https://www.ietf.org/rfc/rfc1321.txt
+class MD5
+{
+public:
+ using Digest = HashDigest<16>;
- MD5();
+ MD5();
- void init();
- void update(const void* data, SlangSizeT size);
- Digest finalize();
+ void init();
+ void update(const void* data, SlangSizeT size);
+ Digest finalize();
- static Digest compute(const void* data, SlangInt size);
+ static Digest compute(const void* data, SlangInt size);
- private:
- const void* processBlock(const void* data, SlangInt size);
+private:
+ const void* processBlock(const void* data, SlangInt size);
- uint32_t m_lo, m_hi;
- uint32_t m_a, m_b, m_c, m_d;
- uint32_t m_block[16];
- uint8_t m_buffer[64];
- };
+ uint32_t m_lo, m_hi;
+ uint32_t m_a, m_b, m_c, m_d;
+ uint32_t m_block[16];
+ uint8_t m_buffer[64];
+};
- /// SHA1 hash generator implementing https://www.ietf.org/rfc/rfc3174.txt
- class SHA1
- {
- public:
- using Digest = HashDigest<20>;
+/// SHA1 hash generator implementing https://www.ietf.org/rfc/rfc3174.txt
+class SHA1
+{
+public:
+ using Digest = HashDigest<20>;
- SHA1();
+ SHA1();
- void init();
- void update(const void* data, SlangSizeT size);
- Digest finalize();
+ void init();
+ void update(const void* data, SlangSizeT size);
+ Digest finalize();
- static Digest compute(const void* data, SlangInt size);
+ static Digest compute(const void* data, SlangInt size);
- private:
- void addByte(uint8_t x);
- void processBlock(const uint8_t* ptr);
+private:
+ void addByte(uint8_t x);
+ void processBlock(const uint8_t* ptr);
- uint32_t m_index;
- uint64_t m_bits;
- uint32_t m_state[5];
- uint8_t m_buf[64];
- };
+ uint32_t m_index;
+ uint64_t m_bits;
+ uint32_t m_state[5];
+ uint8_t m_buf[64];
+};
- // Helper class for building hashes.
- template<typename Hash>
- struct DigestBuilder
+// Helper class for building hashes.
+template<typename Hash>
+struct DigestBuilder
+{
+public:
+ void append(const void* data, SlangInt size) { m_hash.update(data, size); }
+
+ template<
+ typename T,
+ typename std::enable_if<std::is_arithmetic<T>::value || std::is_enum<T>::value, int>::type =
+ 0>
+ void append(const T value)
{
- public:
- void append(const void* data, SlangInt size)
- {
- m_hash.update(data, size);
- }
+ append(&value, sizeof(T));
+ }
- template<typename T, typename std::enable_if<std::is_arithmetic<T>::value || std::is_enum<T>::value, int>::type = 0>
- void append(const T value)
- {
- append(&value, sizeof(T));
- }
+ void append(const String& str) { append(str.getBuffer(), str.getLength()); }
- void append(const String& str)
- {
- append(str.getBuffer(), str.getLength());
- }
-
- void append(const StringSlice& str)
- {
- append(str.begin(), str.getLength());
- }
+ void append(const StringSlice& str) { append(str.begin(), str.getLength()); }
- void append(const UnownedStringSlice& str)
- {
- append(str.begin(), str.getLength());
- }
+ void append(const UnownedStringSlice& str) { append(str.begin(), str.getLength()); }
- void append(ISlangBlob* blob)
- {
- append(blob->getBufferPointer(), blob->getBufferSize());
- }
+ void append(ISlangBlob* blob) { append(blob->getBufferPointer(), blob->getBufferSize()); }
- template<SlangInt N>
- void append(const HashDigest<N>& digest)
- {
- append(digest.data, sizeof(digest.data));
- }
+ template<SlangInt N>
+ void append(const HashDigest<N>& digest)
+ {
+ append(digest.data, sizeof(digest.data));
+ }
- template<typename T, std::enable_if_t<std::has_unique_object_representations_v<T>, int> = 0>
- void append(const List<T>& list)
- {
- append(list.getBuffer(), list.getCount() * sizeof(T));
- }
+ template<typename T, std::enable_if_t<std::has_unique_object_representations_v<T>, int> = 0>
+ void append(const List<T>& list)
+ {
+ append(list.getBuffer(), list.getCount() * sizeof(T));
+ }
- typename Hash::Digest finalize()
- {
- return m_hash.finalize();
- }
+ typename Hash::Digest finalize() { return m_hash.finalize(); }
- private:
- Hash m_hash;
- };
-}
+private:
+ Hash m_hash;
+};
+} // namespace Slang
diff --git a/source/core/slang-deflate-compression-system.cpp b/source/core/slang-deflate-compression-system.cpp
index 4f1390240..1cbea01f0 100644
--- a/source/core/slang-deflate-compression-system.cpp
+++ b/source/core/slang-deflate-compression-system.cpp
@@ -3,13 +3,13 @@
#include "slang-com-helper.h"
#include "slang-com-ptr.h"
-// We don't want compress #define to clash
+// We don't want compress #define to clash
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES 1
-#include <miniz.h>
-
#include "slang-blob.h"
+#include <miniz.h>
+
namespace Slang
{
@@ -18,7 +18,7 @@ namespace Slang
class DeflateCompressionSystemImpl : public RefObject, public ICompressionSystem
{
public:
- // ISlangUnknown
+ // ISlangUnknown
// override ref counting, as singleton
SLANG_IUNKNOWN_QUERY_INTERFACE
@@ -26,28 +26,45 @@ public:
SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
// ICompressionSystem
- virtual SLANG_NO_THROW CompressionSystemType SLANG_MCALL getSystemType() SLANG_OVERRIDE { return CompressionSystemType::Deflate; }
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compress(const CompressionStyle* style, const void* src, size_t srcSizeInBytes, ISlangBlob** outBlob) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL decompress(const void* compressed, size_t compressedSizeInBytes, size_t decompressedSizeInBytes, void* outDecompressed) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW CompressionSystemType SLANG_MCALL getSystemType() SLANG_OVERRIDE
+ {
+ return CompressionSystemType::Deflate;
+ }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compress(
+ const CompressionStyle* style,
+ const void* src,
+ size_t srcSizeInBytes,
+ ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL decompress(
+ const void* compressed,
+ size_t compressedSizeInBytes,
+ size_t decompressedSizeInBytes,
+ void* outDecompressed) SLANG_OVERRIDE;
protected:
-
ICompressionSystem* getInterface(const Guid& guid);
};
ICompressionSystem* DeflateCompressionSystemImpl::getInterface(const Guid& guid)
{
- return (guid == ISlangUnknown::getTypeGuid() || guid == ICompressionSystem::getTypeGuid()) ? static_cast<ICompressionSystem*>(this) : nullptr;
+ return (guid == ISlangUnknown::getTypeGuid() || guid == ICompressionSystem::getTypeGuid())
+ ? static_cast<ICompressionSystem*>(this)
+ : nullptr;
}
-SlangResult DeflateCompressionSystemImpl::compress(const CompressionStyle* style, const void* src, size_t srcSizeInBytes, ISlangBlob** outBlob)
+SlangResult DeflateCompressionSystemImpl::compress(
+ const CompressionStyle* style,
+ const void* src,
+ size_t srcSizeInBytes,
+ ISlangBlob** outBlob)
{
SLANG_UNUSED(style);
size_t compressedSizeInBytes;
const int flags = 0;
- void* compressed = tdefl_compress_mem_to_heap(src, srcSizeInBytes, &compressedSizeInBytes, flags);
+ void* compressed =
+ tdefl_compress_mem_to_heap(src, srcSizeInBytes, &compressedSizeInBytes, flags);
if (!compressed)
{
@@ -62,11 +79,20 @@ SlangResult DeflateCompressionSystemImpl::compress(const CompressionStyle* style
return SLANG_OK;
}
-SlangResult DeflateCompressionSystemImpl::decompress(const void* compressed, size_t compressedSizeInBytes, size_t decompressedSizeInBytes, void* outDecompressed)
+SlangResult DeflateCompressionSystemImpl::decompress(
+ const void* compressed,
+ size_t compressedSizeInBytes,
+ size_t decompressedSizeInBytes,
+ void* outDecompressed)
{
const int flags = TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
- size_t size = tinfl_decompress_mem_to_mem(outDecompressed, decompressedSizeInBytes, compressed ,compressedSizeInBytes, flags);
+ size_t size = tinfl_decompress_mem_to_mem(
+ outDecompressed,
+ decompressedSizeInBytes,
+ compressed,
+ compressedSizeInBytes,
+ flags);
if (size == TINFL_DECOMPRESS_MEM_TO_MEM_FAILED)
{
return SLANG_FAIL;
@@ -75,7 +101,7 @@ SlangResult DeflateCompressionSystemImpl::decompress(const void* compressed, siz
return SLANG_OK;
}
-/* static */ICompressionSystem* DeflateCompressionSystem::getSingleton()
+/* static */ ICompressionSystem* DeflateCompressionSystem::getSingleton()
{
static DeflateCompressionSystemImpl impl;
return &impl;
diff --git a/source/core/slang-deflate-compression-system.h b/source/core/slang-deflate-compression-system.h
index efed59e61..929ad153a 100644
--- a/source/core/slang-deflate-compression-system.h
+++ b/source/core/slang-deflate-compression-system.h
@@ -2,10 +2,8 @@
#define SLANG_DEFLATE_COMPRESSION_SYSTEM_H
#include "slang-basic.h"
-
-#include "slang-compression-system.h"
-
#include "slang-com-ptr.h"
+#include "slang-compression-system.h"
namespace Slang
{
@@ -17,6 +15,6 @@ public:
static ICompressionSystem* getSingleton();
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-dictionary.h b/source/core/slang-dictionary.h
index 9c753ffcd..79f6dee30 100644
--- a/source/core/slang-dictionary.h
+++ b/source/core/slang-dictionary.h
@@ -1,786 +1,752 @@
#ifndef SLANG_CORE_DICTIONARY_H
#define SLANG_CORE_DICTIONARY_H
-#include "slang-list.h"
-#include "slang-linked-list.h"
+#include "../../external/unordered_dense/include/ankerl/unordered_dense.h"
#include "slang-common.h"
-#include "slang-uint-set.h"
#include "slang-exception.h"
-#include "slang-math.h"
#include "slang-hash.h"
-
-#include "../../external/unordered_dense/include/ankerl/unordered_dense.h"
+#include "slang-linked-list.h"
+#include "slang-list.h"
+#include "slang-math.h"
+#include "slang-uint-set.h"
#include <initializer_list>
namespace Slang
{
- template<typename TKey, typename TValue>
- class KeyValuePair
+template<typename TKey, typename TValue>
+class KeyValuePair
+{
+public:
+ TKey key;
+ TValue value;
+ KeyValuePair() {}
+ KeyValuePair(const TKey& inKey, const TValue& inValue)
{
- public:
- TKey key;
- TValue value;
- KeyValuePair()
- {}
- KeyValuePair(const TKey& inKey, const TValue& inValue)
- {
- key = inKey;
- value = inValue;
- }
- KeyValuePair(TKey&& inKey, TValue&& inValue)
- {
- key = _Move(inKey);
- value = _Move(inValue);
- }
- KeyValuePair(TKey&& inKey, const TValue& inValue)
- {
- key = _Move(inKey);
- value = inValue;
- }
- KeyValuePair(const KeyValuePair<TKey, TValue>& that)
- {
- key = that.key;
- value = that.value;
- }
- KeyValuePair(KeyValuePair<TKey, TValue>&& that)
- {
- operator=(_Move(that));
- }
- KeyValuePair& operator=(KeyValuePair<TKey, TValue>&& that)
- {
- key = _Move(that.key);
- value = _Move(that.value);
- return *this;
- }
- KeyValuePair& operator=(const KeyValuePair<TKey, TValue>& that)
- {
- key = that.key;
- value = that.value;
- return *this;
- }
- HashCode getHashCode() const
- {
- return combineHash(
- Slang::getHashCode(key),
- Slang::getHashCode(value));
- }
- bool operator==(const KeyValuePair<TKey, TValue>& that) const
- {
- return (key == that.key) && (value == that.value);
- }
- };
-
- template<typename TKey, typename TValue>
- inline KeyValuePair<TKey, TValue> KVPair(const TKey& k, const TValue& v)
+ key = inKey;
+ value = inValue;
+ }
+ KeyValuePair(TKey&& inKey, TValue&& inValue)
{
- return KeyValuePair<TKey, TValue>(k, v);
+ key = _Move(inKey);
+ value = _Move(inValue);
}
-
- namespace KeyValueDetail {
-
- template <typename KEY, typename VALUE>
- SLANG_FORCE_INLINE const KEY* getKey(const std::pair<KEY, VALUE>* in)
+ KeyValuePair(TKey&& inKey, const TValue& inValue)
{
- return &in->first;
+ key = _Move(inKey);
+ value = inValue;
}
- template <typename KEY, typename VALUE>
- SLANG_FORCE_INLINE const KEY* getKey(const KeyValuePair<KEY, VALUE>* in)
+ KeyValuePair(const KeyValuePair<TKey, TValue>& that)
{
- return &in->key;
+ key = that.key;
+ value = that.value;
}
-
- template <typename KEY, typename VALUE>
- SLANG_FORCE_INLINE const VALUE* getValue(const std::pair<KEY, VALUE>* in)
+ KeyValuePair(KeyValuePair<TKey, TValue>&& that) { operator=(_Move(that)); }
+ KeyValuePair& operator=(KeyValuePair<TKey, TValue>&& that)
+ {
+ key = _Move(that.key);
+ value = _Move(that.value);
+ return *this;
+ }
+ KeyValuePair& operator=(const KeyValuePair<TKey, TValue>& that)
+ {
+ key = that.key;
+ value = that.value;
+ return *this;
+ }
+ HashCode getHashCode() const
{
- return &in->second;
+ return combineHash(Slang::getHashCode(key), Slang::getHashCode(value));
}
- template <typename KEY, typename VALUE>
- SLANG_FORCE_INLINE const VALUE* getValue(const KeyValuePair<KEY, VALUE>* in)
+ bool operator==(const KeyValuePair<TKey, TValue>& that) const
{
- return &in->value;
+ return (key == that.key) && (value == that.value);
}
+};
- } // namespace KeyValueDetail
+template<typename TKey, typename TValue>
+inline KeyValuePair<TKey, TValue> KVPair(const TKey& k, const TValue& v)
+{
+ return KeyValuePair<TKey, TValue>(k, v);
+}
+
+namespace KeyValueDetail
+{
+
+template<typename KEY, typename VALUE>
+SLANG_FORCE_INLINE const KEY* getKey(const std::pair<KEY, VALUE>* in)
+{
+ return &in->first;
+}
+template<typename KEY, typename VALUE>
+SLANG_FORCE_INLINE const KEY* getKey(const KeyValuePair<KEY, VALUE>* in)
+{
+ return &in->key;
+}
+
+template<typename KEY, typename VALUE>
+SLANG_FORCE_INLINE const VALUE* getValue(const std::pair<KEY, VALUE>* in)
+{
+ return &in->second;
+}
+template<typename KEY, typename VALUE>
+SLANG_FORCE_INLINE const VALUE* getValue(const KeyValuePair<KEY, VALUE>* in)
+{
+ return &in->value;
+}
- const float kMaxLoadFactor = 0.7f;
+} // namespace KeyValueDetail
- template<typename TKey, typename TValue, typename Hash = Slang::Hash<TKey>, typename KeyEqual = std::equal_to<TKey>>
- class Dictionary
+const float kMaxLoadFactor = 0.7f;
+
+template<
+ typename TKey,
+ typename TValue,
+ typename Hash = Slang::Hash<TKey>,
+ typename KeyEqual = std::equal_to<TKey>>
+class Dictionary
+{
+ using InnerMap = ankerl::unordered_dense::map<TKey, TValue, Hash, KeyEqual>;
+ using ThisType = Dictionary<TKey, TValue, Hash, KeyEqual>;
+ InnerMap map;
+
+public:
+ Dictionary() = default;
+ Dictionary(const Dictionary&) = default;
+ Dictionary(Dictionary&&) = default;
+ ThisType& operator=(const ThisType&) = default;
+ ThisType& operator=(ThisType&&) = default;
+ Dictionary(std::initializer_list<typename InnerMap::value_type> inits)
+ : map(std::move(inits))
{
- using InnerMap = ankerl::unordered_dense::map<
- TKey,
- TValue,
- Hash,
- KeyEqual>;
- using ThisType = Dictionary<TKey, TValue, Hash, KeyEqual>;
- InnerMap map;
- public:
- Dictionary() = default;
- Dictionary(const Dictionary&) = default;
- Dictionary(Dictionary&&) = default;
- ThisType& operator=(const ThisType&) = default;
- ThisType& operator=(ThisType&&) = default;
- Dictionary(std::initializer_list<typename InnerMap::value_type> inits)
- : map(std::move(inits))
- {
- }
+ }
- //
- // Types
- //
- using Iterator = typename InnerMap::iterator;
- using ConstIterator = typename InnerMap::const_iterator;
- using KeyType = TKey;
- using ValueType = TValue;
+ //
+ // Types
+ //
+ using Iterator = typename InnerMap::iterator;
+ using ConstIterator = typename InnerMap::const_iterator;
+ using KeyType = TKey;
+ using ValueType = TValue;
- //
- // Iterators
- //
+ //
+ // Iterators
+ //
- auto begin() { return map.begin(); }
- auto begin() const { return map.begin(); }
- auto end() { return map.end(); }
- auto end() const { return map.end(); }
+ auto begin() { return map.begin(); }
+ auto begin() const { return map.begin(); }
+ auto end() { return map.end(); }
+ auto end() const { return map.end(); }
- //
- // Modifiers
- //
+ //
+ // Modifiers
+ //
- // Removes all values from the map
- void clear() { map.clear(); }
+ // Removes all values from the map
+ void clear() { map.clear(); }
- // Erases the value at the specified key if it exists
- void remove(const TKey& key) { map.erase(key); }
+ // Erases the value at the specified key if it exists
+ void remove(const TKey& key) { map.erase(key); }
- // Reserves enough space for the specified number of values
- void reserve(Index size) { map.reserve(std::size_t(size)); };
+ // Reserves enough space for the specified number of values
+ void reserve(Index size) { map.reserve(std::size_t(size)); };
- // Swap with another map
- void swapWith(ThisType& rhs) { std::swap(*this, rhs); }
+ // Swap with another map
+ void swapWith(ThisType& rhs) { std::swap(*this, rhs); }
- //
- // Query capacity
- //
+ //
+ // Query capacity
+ //
- std::size_t getCount() const { return map.size(); }
+ std::size_t getCount() const { return map.size(); }
- //
- // Lookup
- //
+ //
+ // Lookup
+ //
- // Returns true if the map contains an equivalent key
- template<typename K>
- bool containsKey(const K& k) const { return map.contains(k); }
+ // Returns true if the map contains an equivalent key
+ template<typename K>
+ bool containsKey(const K& k) const
+ {
+ return map.contains(k);
+ }
- // Returns a valid pointer to the requested element, or nullptr if it
- // doesn't exist
- template<typename K>
- const TValue* tryGetValue(const K& key) const
- {
- auto i = map.find(key);
- return i == map.end() ? nullptr : &(i->second);
- }
- // Returns a valid pointer to the requested element, or nullptr if it
- // doesn't exist
- template<typename K>
- TValue* tryGetValue(const K& key)
- {
- auto i = map.find(key);
- return i == map.end() ? nullptr : std::addressof(i->second);
- }
+ // Returns a valid pointer to the requested element, or nullptr if it
+ // doesn't exist
+ template<typename K>
+ const TValue* tryGetValue(const K& key) const
+ {
+ auto i = map.find(key);
+ return i == map.end() ? nullptr : &(i->second);
+ }
+ // Returns a valid pointer to the requested element, or nullptr if it
+ // doesn't exist
+ template<typename K>
+ TValue* tryGetValue(const K& key)
+ {
+ auto i = map.find(key);
+ return i == map.end() ? nullptr : std::addressof(i->second);
+ }
- // Returns true and copies the element into 'value' if present.
- // Otherwise returns false and value unmodified.
- template<typename K>
- bool tryGetValue(const K& key, TValue& value) const
- {
- auto i = map.find(key);
- if(i == map.end())
- return false;
- value = i->second;
- return true;
- }
+ // Returns true and copies the element into 'value' if present.
+ // Otherwise returns false and value unmodified.
+ template<typename K>
+ bool tryGetValue(const K& key, TValue& value) const
+ {
+ auto i = map.find(key);
+ if (i == map.end())
+ return false;
+ value = i->second;
+ return true;
+ }
- // Returns a const reference to the value at the given key. Asserts if
- // the value doesn't exist
- const TValue& getValue(const TKey& key) const
- {
- if(const auto x = tryGetValue(key))
- return *x;
- SLANG_ASSERT_FAILURE("The key does not exist in dictionary.");
- }
+ // Returns a const reference to the value at the given key. Asserts if
+ // the value doesn't exist
+ const TValue& getValue(const TKey& key) const
+ {
+ if (const auto x = tryGetValue(key))
+ return *x;
+ SLANG_ASSERT_FAILURE("The key does not exist in dictionary.");
+ }
- // Returns a reference to the value at the given key. Asserts if the
- // value doesn't exist
- TValue& getValue(const TKey& key)
- {
- if(const auto x = tryGetValue(key))
- return *x;
- SLANG_ASSERT_FAILURE("The key does not exist in dictionary.");
- }
+ // Returns a reference to the value at the given key. Asserts if the
+ // value doesn't exist
+ TValue& getValue(const TKey& key)
+ {
+ if (const auto x = tryGetValue(key))
+ return *x;
+ SLANG_ASSERT_FAILURE("The key does not exist in dictionary.");
+ }
- //
- // Combined Lookup and Insertion
- //
+ //
+ // Combined Lookup and Insertion
+ //
- // Tries to insert the given element, if a value was already present at
- // the given key then returns a pointer to that element instead.
- // Returns nullptr if insertion was successful.
- TValue* tryGetValueOrAdd(const typename InnerMap::value_type& kvPair)
- {
- const auto& [iterator, inserted] = map.insert(kvPair);
- return inserted ? nullptr : std::addressof(iterator->second);
- }
- // Tries to insert the given element, if a value was already present at
- // the given key then returns a pointer to that element instead.
- // Returns nullptr if insertion was successful.
- TValue* tryGetValueOrAdd(typename InnerMap::value_type&& kvPair)
- {
- const auto& [iterator, inserted] = map.insert(std::move(kvPair));
- return inserted ? nullptr : std::addressof(iterator->second);
- }
- // Tries to insert the given element, if a value was already present at
- // the given key then returns a pointer to that element instead.
- // Returns nullptr if insertion was successful.
- TValue* tryGetValueOrAdd(const TKey& key, const TValue& value) { return tryGetValueOrAdd({key, value}); }
-
- // Inserts the given value if it doesn't exist already
- // Return a reference to the (possibly new) value in the map
- TValue& getOrAddValue(const TKey& key, const TValue& defaultValue)
- {
- auto [iterator, inserted] = map.insert({key, defaultValue});
- return iterator->second;
- }
+ // Tries to insert the given element, if a value was already present at
+ // the given key then returns a pointer to that element instead.
+ // Returns nullptr if insertion was successful.
+ TValue* tryGetValueOrAdd(const typename InnerMap::value_type& kvPair)
+ {
+ const auto& [iterator, inserted] = map.insert(kvPair);
+ return inserted ? nullptr : std::addressof(iterator->second);
+ }
+ // Tries to insert the given element, if a value was already present at
+ // the given key then returns a pointer to that element instead.
+ // Returns nullptr if insertion was successful.
+ TValue* tryGetValueOrAdd(typename InnerMap::value_type&& kvPair)
+ {
+ const auto& [iterator, inserted] = map.insert(std::move(kvPair));
+ return inserted ? nullptr : std::addressof(iterator->second);
+ }
+ // Tries to insert the given element, if a value was already present at
+ // the given key then returns a pointer to that element instead.
+ // Returns nullptr if insertion was successful.
+ TValue* tryGetValueOrAdd(const TKey& key, const TValue& value)
+ {
+ return tryGetValueOrAdd({key, value});
+ }
- // Returns a reference to the value at the specified key, default
- // initializing it if it doesn't already exist
- TValue& operator[]( const TKey& key ) { return map[key]; }
- // Returns a reference to the value at the specified key, default
- // initializing it if it doesn't already exist
- TValue& operator[]( TKey&& key ) { return map[std::move(key)]; }
-
- //
- // Insertion
- //
-
- // Returns true if the value was inserted, returns false if the map
- // already has a value associated with this key
- bool addIfNotExists(typename InnerMap::value_type&& kvPair) { return !tryGetValueOrAdd(std::move(kvPair)); }
- // Returns true if the value was inserted, returns false if the map
- // already has a value associated with this key
- bool addIfNotExists(const typename InnerMap::value_type& kvPair) { return !tryGetValueOrAdd(kvPair); }
- // Returns true if the value was inserted, returns false if the map
- // already has a value associated with this key
- bool addIfNotExists(const TKey& k, const TValue& v) { return addIfNotExists({k, v}); }
- // Returns true if the value was inserted, returns false if the map
- // already has a value associated with this key
- bool addIfNotExists(TKey&& k, TValue&& v) { return addIfNotExists({std::move(k), std::move(v)}); }
-
- // Asserts if the key already exists in the dictionary
- void add(typename InnerMap::value_type&& kvPair)
- {
- if (!addIfNotExists(std::move(kvPair)))
- SLANG_ASSERT_FAILURE("The key already exists in Dictionary.");
- }
- // Asserts if the key already exists in the dictionary
- void add(const typename InnerMap::value_type& kvPair)
- {
- if (!addIfNotExists(kvPair))
- SLANG_ASSERT_FAILURE("The key already exists in Dictionary.");
- }
- // Asserts if the key already exists in the dictionary
- void add(const TKey& key, const TValue& value) { add({key, value}); }
- // Asserts if the key already exists in the dictionary
- void add(TKey&& key, TValue&& value) { add({std::move(key), std::move(value)}); }
+ // Inserts the given value if it doesn't exist already
+ // Return a reference to the (possibly new) value in the map
+ TValue& getOrAddValue(const TKey& key, const TValue& defaultValue)
+ {
+ auto [iterator, inserted] = map.insert({key, defaultValue});
+ return iterator->second;
+ }
- // Inserts into the dictionary or assigns if the key already exists
- void set(const TKey& key, const TValue& value) { map.insert_or_assign(key, value); }
- };
+ // Returns a reference to the value at the specified key, default
+ // initializing it if it doesn't already exist
+ TValue& operator[](const TKey& key) { return map[key]; }
+ // Returns a reference to the value at the specified key, default
+ // initializing it if it doesn't already exist
+ TValue& operator[](TKey&& key) { return map[std::move(key)]; }
+
+ //
+ // Insertion
+ //
+
+ // Returns true if the value was inserted, returns false if the map
+ // already has a value associated with this key
+ bool addIfNotExists(typename InnerMap::value_type&& kvPair)
+ {
+ return !tryGetValueOrAdd(std::move(kvPair));
+ }
+ // Returns true if the value was inserted, returns false if the map
+ // already has a value associated with this key
+ bool addIfNotExists(const typename InnerMap::value_type& kvPair)
+ {
+ return !tryGetValueOrAdd(kvPair);
+ }
+ // Returns true if the value was inserted, returns false if the map
+ // already has a value associated with this key
+ bool addIfNotExists(const TKey& k, const TValue& v) { return addIfNotExists({k, v}); }
+ // Returns true if the value was inserted, returns false if the map
+ // already has a value associated with this key
+ bool addIfNotExists(TKey&& k, TValue&& v)
+ {
+ return addIfNotExists({std::move(k), std::move(v)});
+ }
+
+ // Asserts if the key already exists in the dictionary
+ void add(typename InnerMap::value_type&& kvPair)
+ {
+ if (!addIfNotExists(std::move(kvPair)))
+ SLANG_ASSERT_FAILURE("The key already exists in Dictionary.");
+ }
+ // Asserts if the key already exists in the dictionary
+ void add(const typename InnerMap::value_type& kvPair)
+ {
+ if (!addIfNotExists(kvPair))
+ SLANG_ASSERT_FAILURE("The key already exists in Dictionary.");
+ }
+ // Asserts if the key already exists in the dictionary
+ void add(const TKey& key, const TValue& value) { add({key, value}); }
+ // Asserts if the key already exists in the dictionary
+ void add(TKey&& key, TValue&& value) { add({std::move(key), std::move(value)}); }
+
+ // Inserts into the dictionary or assigns if the key already exists
+ void set(const TKey& key, const TValue& value) { map.insert_or_assign(key, value); }
+};
- /* We may want to rename this, as strictly speaking _Caps names are reserved */
- class _DummyClass
- {};
+/* We may want to rename this, as strictly speaking _Caps names are reserved */
+class _DummyClass
+{
+};
+
+template<typename T, typename DictionaryType>
+class HashSetBase
+{
+protected:
+ DictionaryType dict;
+
+private:
+ template<typename... Args>
+ void init(const T& v, Args... args)
+ {
+ add(v);
+ init(args...);
+ }
- template<typename T, typename DictionaryType>
- class HashSetBase
+public:
+ HashSetBase() {}
+ template<typename Arg, typename... Args>
+ HashSetBase(Arg arg, Args... args)
+ {
+ init(arg, args...);
+ }
+ HashSetBase(const HashSetBase& set) { operator=(set); }
+ HashSetBase(HashSetBase&& set) { operator=(_Move(set)); }
+ HashSetBase& operator=(const HashSetBase& set)
+ {
+ dict = set.dict;
+ return *this;
+ }
+ HashSetBase& operator=(HashSetBase&& set)
+ {
+ dict = _Move(set.dict);
+ return *this;
+ }
+
+public:
+ class Iterator
{
- protected:
- DictionaryType dict;
private:
- template<typename... Args>
- void init(const T& v, Args... args)
- {
- add(v);
- init(args...);
- }
- public:
- HashSetBase()
- {}
- template<typename Arg, typename... Args>
- HashSetBase(Arg arg, Args... args)
- {
- init(arg, args...);
- }
- HashSetBase(const HashSetBase& set)
- {
- operator=(set);
- }
- HashSetBase(HashSetBase&& set)
- {
- operator=(_Move(set));
- }
- HashSetBase& operator=(const HashSetBase& set)
- {
- dict = set.dict;
- return *this;
- }
- HashSetBase& operator=(HashSetBase&& set)
- {
- dict = _Move(set.dict);
- return *this;
- }
- public:
- class Iterator
- {
- private:
- typename DictionaryType::ConstIterator iter;
- public:
- Iterator() = default;
- const T& operator*() const
- {
- return *KeyValueDetail::getKey(std::addressof(*iter));
- }
- const T* operator->() const
- {
- return KeyValueDetail::getKey(std::addressof(*iter));
- }
+ typename DictionaryType::ConstIterator iter;
- Iterator& operator++()
- {
- ++iter;
- return *this;
- }
- Iterator operator++(int)
- {
- Iterator rs = *this;
- operator++();
- return rs;
- }
- bool operator!=(const Iterator& that) const
- {
- return iter != that.iter;
- }
- bool operator==(const Iterator& that) const
- {
- return iter == that.iter;
- }
- Iterator(const typename DictionaryType::ConstIterator& _iter)
- {
- this->iter = _iter;
- }
- };
- Iterator begin() const
- {
- return Iterator(dict.begin());
- }
- Iterator end() const
- {
- return Iterator(dict.end());
- }
public:
- auto getCount() const
- {
- return dict.getCount();
- }
- void clear()
- {
- dict.clear();
- }
- bool add(const T& obj)
- {
- return dict.addIfNotExists(obj, _DummyClass());
- }
- bool add(T&& obj)
- {
- return dict.addIfNotExists(_Move(obj), _DummyClass());
- }
- void remove(const T& obj)
+ Iterator() = default;
+ const T& operator*() const { return *KeyValueDetail::getKey(std::addressof(*iter)); }
+ const T* operator->() const { return KeyValueDetail::getKey(std::addressof(*iter)); }
+
+ Iterator& operator++()
{
- dict.remove(obj);
+ ++iter;
+ return *this;
}
- bool contains(const T& obj) const
+ Iterator operator++(int)
{
- return dict.containsKey(obj);
+ Iterator rs = *this;
+ operator++();
+ return rs;
}
+ bool operator!=(const Iterator& that) const { return iter != that.iter; }
+ bool operator==(const Iterator& that) const { return iter == that.iter; }
+ Iterator(const typename DictionaryType::ConstIterator& _iter) { this->iter = _iter; }
};
- template <typename T>
- class HashSet : public HashSetBase<T, Dictionary<T, _DummyClass>>
- {};
+ Iterator begin() const { return Iterator(dict.begin()); }
+ Iterator end() const { return Iterator(dict.end()); }
+
+public:
+ auto getCount() const { return dict.getCount(); }
+ void clear() { dict.clear(); }
+ bool add(const T& obj) { return dict.addIfNotExists(obj, _DummyClass()); }
+ bool add(T&& obj) { return dict.addIfNotExists(_Move(obj), _DummyClass()); }
+ void remove(const T& obj) { dict.remove(obj); }
+ bool contains(const T& obj) const { return dict.containsKey(obj); }
+};
+template<typename T>
+class HashSet : public HashSetBase<T, Dictionary<T, _DummyClass>>
+{
+};
- template <typename TKey, typename TValue>
- class OrderedDictionary
- {
- friend class Iterator;
- friend class ItemProxy;
+template<typename TKey, typename TValue>
+class OrderedDictionary
+{
+ friend class Iterator;
+ friend class ItemProxy;
- private:
- inline int getProbeOffset(int /*probeIdx*/) const
- {
- // quadratic probing
- return 1;
- }
+private:
+ inline int getProbeOffset(int /*probeIdx*/) const
+ {
+ // quadratic probing
+ return 1;
+ }
- private:
- int m_bucketCountMinusOne;
- int m_count;
- UIntSet m_marks;
+private:
+ int m_bucketCountMinusOne;
+ int m_count;
+ UIntSet m_marks;
- LinkedList<KeyValuePair<TKey, TValue>> m_kvPairs;
- LinkedNode<KeyValuePair<TKey, TValue>>** m_hashMap;
- void deallocateAll()
- {
- if (m_hashMap)
- delete[] m_hashMap;
- m_hashMap = nullptr;
- m_kvPairs.clear();
- }
- inline bool isDeleted(int pos) const { return m_marks.contains((pos << 1) + 1); }
- inline bool isEmpty(int pos) const { return !m_marks.contains((pos << 1)); }
- inline void setDeleted(int pos, bool val)
+ LinkedList<KeyValuePair<TKey, TValue>> m_kvPairs;
+ LinkedNode<KeyValuePair<TKey, TValue>>** m_hashMap;
+ void deallocateAll()
+ {
+ if (m_hashMap)
+ delete[] m_hashMap;
+ m_hashMap = nullptr;
+ m_kvPairs.clear();
+ }
+ inline bool isDeleted(int pos) const { return m_marks.contains((pos << 1) + 1); }
+ inline bool isEmpty(int pos) const { return !m_marks.contains((pos << 1)); }
+ inline void setDeleted(int pos, bool val)
+ {
+ if (val)
+ m_marks.add((pos << 1) + 1);
+ else
+ m_marks.remove((pos << 1) + 1);
+ }
+ inline void setEmpty(int pos, bool val)
+ {
+ if (val)
+ m_marks.remove((pos << 1));
+ else
+ m_marks.add((pos << 1));
+ }
+ struct FindPositionResult
+ {
+ int objectPosition;
+ int insertionPosition;
+ FindPositionResult()
{
- if (val)
- m_marks.add((pos << 1) + 1);
- else
- m_marks.remove((pos << 1) + 1);
+ objectPosition = -1;
+ insertionPosition = -1;
}
- inline void setEmpty(int pos, bool val)
+ FindPositionResult(int objPos, int insertPos)
{
- if (val)
- m_marks.remove((pos << 1));
- else
- m_marks.add((pos << 1));
+ objectPosition = objPos;
+ insertionPosition = insertPos;
}
- struct FindPositionResult
+ };
+ template<typename T>
+ inline int getHashPos(T& key) const
+ {
+ const unsigned int hash = (unsigned int)getHashCode(key);
+ return ((unsigned int)(hash * 2654435761)) % m_bucketCountMinusOne;
+ }
+ template<typename T>
+ FindPositionResult findPosition(const T& key) const
+ {
+ int hashPos = getHashPos((T&)key);
+ int insertPos = -1;
+ int numProbes = 0;
+ while (numProbes <= m_bucketCountMinusOne)
{
- int objectPosition;
- int insertionPosition;
- FindPositionResult()
+ if (isEmpty(hashPos))
{
- objectPosition = -1;
- insertionPosition = -1;
+ if (insertPos == -1)
+ return FindPositionResult(-1, hashPos);
+ else
+ return FindPositionResult(-1, insertPos);
}
- FindPositionResult(int objPos, int insertPos)
+ else if (isDeleted(hashPos))
{
- objectPosition = objPos;
- insertionPosition = insertPos;
+ if (insertPos == -1)
+ insertPos = hashPos;
}
- };
- template <typename T> inline int getHashPos(T& key) const
- {
- const unsigned int hash = (unsigned int)getHashCode(key);
- return ((unsigned int)(hash * 2654435761)) % m_bucketCountMinusOne;
- }
- template <typename T> FindPositionResult findPosition(const T& key) const
- {
- int hashPos = getHashPos((T&)key);
- int insertPos = -1;
- int numProbes = 0;
- while (numProbes <= m_bucketCountMinusOne)
+ else if (m_hashMap[hashPos]->value.key == key)
{
- if (isEmpty(hashPos))
- {
- if (insertPos == -1)
- return FindPositionResult(-1, hashPos);
- else
- return FindPositionResult(-1, insertPos);
- }
- else if (isDeleted(hashPos))
- {
- if (insertPos == -1)
- insertPos = hashPos;
- }
- else if (m_hashMap[hashPos]->value.key == key)
- {
- return FindPositionResult(hashPos, -1);
- }
- numProbes++;
- hashPos = (hashPos + getProbeOffset(numProbes)) & m_bucketCountMinusOne;
+ return FindPositionResult(hashPos, -1);
}
- if (insertPos != -1)
- return FindPositionResult(-1, insertPos);
- SLANG_ASSERT_FAILURE("Hash map is full. This indicates an error in Key::Equal or Key::GetHashCode.");
+ numProbes++;
+ hashPos = (hashPos + getProbeOffset(numProbes)) & m_bucketCountMinusOne;
}
- TValue& _insert(KeyValuePair<TKey, TValue>&& kvPair, int pos)
- {
- auto node = m_kvPairs.addLast();
- node->value = _Move(kvPair);
- m_hashMap[pos] = node;
- setEmpty(pos, false);
- setDeleted(pos, false);
- return node->value.value;
- }
- void maybeRehash()
+ if (insertPos != -1)
+ return FindPositionResult(-1, insertPos);
+ SLANG_ASSERT_FAILURE(
+ "Hash map is full. This indicates an error in Key::Equal or Key::GetHashCode.");
+ }
+ TValue& _insert(KeyValuePair<TKey, TValue>&& kvPair, int pos)
+ {
+ auto node = m_kvPairs.addLast();
+ node->value = _Move(kvPair);
+ m_hashMap[pos] = node;
+ setEmpty(pos, false);
+ setDeleted(pos, false);
+ return node->value.value;
+ }
+ void maybeRehash()
+ {
+ if (m_bucketCountMinusOne == -1 || m_count / (float)m_bucketCountMinusOne >= kMaxLoadFactor)
{
- if (m_bucketCountMinusOne == -1 || m_count / (float)m_bucketCountMinusOne >= kMaxLoadFactor)
+ int newSize = (m_bucketCountMinusOne + 1) * 2;
+ if (newSize == 0)
{
- int newSize = (m_bucketCountMinusOne + 1) * 2;
- if (newSize == 0)
- {
- newSize = 128;
- }
- OrderedDictionary<TKey, TValue> newDict;
- newDict.m_bucketCountMinusOne = newSize - 1;
- newDict.m_hashMap = new LinkedNode<KeyValuePair<TKey, TValue>>*[newSize];
- newDict.m_marks.resizeAndClear(newSize * 2);
- if (m_hashMap)
+ newSize = 128;
+ }
+ OrderedDictionary<TKey, TValue> newDict;
+ newDict.m_bucketCountMinusOne = newSize - 1;
+ newDict.m_hashMap = new LinkedNode<KeyValuePair<TKey, TValue>>*[newSize];
+ newDict.m_marks.resizeAndClear(newSize * 2);
+ if (m_hashMap)
+ {
+ for (auto& kvPair : *this)
{
- for (auto& kvPair : *this)
- {
- newDict.add(_Move(kvPair));
- }
+ newDict.add(_Move(kvPair));
}
- *this = _Move(newDict);
}
+ *this = _Move(newDict);
}
+ }
- bool addIfNotExists(KeyValuePair<TKey, TValue>&& kvPair)
+ bool addIfNotExists(KeyValuePair<TKey, TValue>&& kvPair)
+ {
+ maybeRehash();
+ auto pos = findPosition(kvPair.key);
+ if (pos.objectPosition != -1)
+ return false;
+ else if (pos.insertionPosition != -1)
{
- maybeRehash();
- auto pos = findPosition(kvPair.key);
- if (pos.objectPosition != -1)
- return false;
- else if (pos.insertionPosition != -1)
- {
- m_count++;
- _insert(_Move(kvPair), pos.insertionPosition);
- return true;
- }
- else
- SLANG_ASSERT_FAILURE("Inconsistent find result returned. This is a bug in Dictionary implementation.");
+ m_count++;
+ _insert(_Move(kvPair), pos.insertionPosition);
+ return true;
}
- void add(KeyValuePair<TKey, TValue>&& kvPair)
+ else
+ SLANG_ASSERT_FAILURE(
+ "Inconsistent find result returned. This is a bug in Dictionary implementation.");
+ }
+ void add(KeyValuePair<TKey, TValue>&& kvPair)
+ {
+ if (!addIfNotExists(_Move(kvPair)))
+ SLANG_ASSERT_FAILURE("The key already exists in Dictionary.");
+ }
+ TValue& set(KeyValuePair<TKey, TValue>&& kvPair)
+ {
+ maybeRehash();
+ auto pos = findPosition(kvPair.key);
+ if (pos.objectPosition != -1)
{
- if (!addIfNotExists(_Move(kvPair)))
- SLANG_ASSERT_FAILURE("The key already exists in Dictionary.");
+ m_hashMap[pos.objectPosition]->removeAndDelete();
+ return _insert(_Move(kvPair), pos.objectPosition);
}
- TValue& set(KeyValuePair<TKey, TValue>&& kvPair)
+ else if (pos.insertionPosition != -1)
{
- maybeRehash();
- auto pos = findPosition(kvPair.key);
- if (pos.objectPosition != -1)
- {
- m_hashMap[pos.objectPosition]->removeAndDelete();
- return _insert(_Move(kvPair), pos.objectPosition);
- }
- else if (pos.insertionPosition != -1)
- {
- m_count++;
- return _insert(_Move(kvPair), pos.insertionPosition);
- }
- else
- SLANG_ASSERT_FAILURE("Inconsistent find result returned. This is a bug in Dictionary implementation.");
+ m_count++;
+ return _insert(_Move(kvPair), pos.insertionPosition);
}
+ else
+ SLANG_ASSERT_FAILURE(
+ "Inconsistent find result returned. This is a bug in Dictionary implementation.");
+ }
- public:
- using Iterator = typename LinkedList<KeyValuePair<TKey, TValue>>::Iterator;
- using ConstIterator = typename LinkedList<KeyValuePair<TKey, TValue>>::ConstIterator;
+public:
+ using Iterator = typename LinkedList<KeyValuePair<TKey, TValue>>::Iterator;
+ using ConstIterator = typename LinkedList<KeyValuePair<TKey, TValue>>::ConstIterator;
- Iterator begin() { return m_kvPairs.begin(); }
- Iterator end() { return m_kvPairs.end(); }
- ConstIterator begin() const { return m_kvPairs.begin(); }
- ConstIterator end() const { return m_kvPairs.end(); }
+ Iterator begin() { return m_kvPairs.begin(); }
+ Iterator end() { return m_kvPairs.end(); }
+ ConstIterator begin() const { return m_kvPairs.begin(); }
+ ConstIterator end() const { return m_kvPairs.end(); }
- public:
- void add(const TKey& key, const TValue& value)
- {
- add(KeyValuePair<TKey, TValue>(key, value));
- }
- void add(TKey&& key, TValue&& value)
- {
- add(KeyValuePair<TKey, TValue>(_Move(key), _Move(value)));
- }
- bool addIfNotExists(const TKey& key, const TValue& value)
- {
- return addIfNotExists(KeyValuePair<TKey, TValue>(key, value));
- }
- bool addIfNotExists(TKey&& key, TValue&& value)
- {
- return addIfNotExists(KeyValuePair<TKey, TValue>(_Move(key), _Move(value)));
- }
- void remove(const TKey& key)
- {
- if (m_count > 0)
- {
- auto pos = findPosition(key);
- if (pos.objectPosition != -1)
- {
- m_kvPairs.removeAndDelete(m_hashMap[pos.objectPosition]);
- m_hashMap[pos.objectPosition] = 0;
- setDeleted(pos.objectPosition, true);
- m_count--;
- }
- }
- }
- void clear()
- {
- m_count = 0;
- m_kvPairs.clear();
- m_marks.clear();
- }
- template <typename T> bool containsKey(const T& key) const
- {
- if (m_bucketCountMinusOne == -1)
- return false;
- auto pos = findPosition(key);
- return pos.objectPosition != -1;
- }
- template <typename T> TValue* tryGetValue(const T& key) const
+public:
+ void add(const TKey& key, const TValue& value) { add(KeyValuePair<TKey, TValue>(key, value)); }
+ void add(TKey&& key, TValue&& value)
+ {
+ add(KeyValuePair<TKey, TValue>(_Move(key), _Move(value)));
+ }
+ bool addIfNotExists(const TKey& key, const TValue& value)
+ {
+ return addIfNotExists(KeyValuePair<TKey, TValue>(key, value));
+ }
+ bool addIfNotExists(TKey&& key, TValue&& value)
+ {
+ return addIfNotExists(KeyValuePair<TKey, TValue>(_Move(key), _Move(value)));
+ }
+ void remove(const TKey& key)
+ {
+ if (m_count > 0)
{
- if (m_bucketCountMinusOne == -1)
- return nullptr;
auto pos = findPosition(key);
if (pos.objectPosition != -1)
{
- return &(m_hashMap[pos.objectPosition]->value.value);
+ m_kvPairs.removeAndDelete(m_hashMap[pos.objectPosition]);
+ m_hashMap[pos.objectPosition] = 0;
+ setDeleted(pos.objectPosition, true);
+ m_count--;
}
- return nullptr;
}
- template <typename T> bool tryGetValue(const T& key, TValue& value) const
- {
- if (m_bucketCountMinusOne == -1)
- return false;
- auto pos = findPosition(key);
- if (pos.objectPosition != -1)
- {
- value = m_hashMap[pos.objectPosition]->value.value;
- return true;
- }
+ }
+ void clear()
+ {
+ m_count = 0;
+ m_kvPairs.clear();
+ m_marks.clear();
+ }
+ template<typename T>
+ bool containsKey(const T& key) const
+ {
+ if (m_bucketCountMinusOne == -1)
return false;
- }
- class ItemProxy
+ auto pos = findPosition(key);
+ return pos.objectPosition != -1;
+ }
+ template<typename T>
+ TValue* tryGetValue(const T& key) const
+ {
+ if (m_bucketCountMinusOne == -1)
+ return nullptr;
+ auto pos = findPosition(key);
+ if (pos.objectPosition != -1)
{
- private:
- const OrderedDictionary<TKey, TValue>* dict;
- TKey key;
-
- public:
- ItemProxy(const TKey& _key, const OrderedDictionary<TKey, TValue>* _dict)
- {
- this->dict = _dict;
- this->key = _key;
- }
- ItemProxy(TKey&& _key, const OrderedDictionary<TKey, TValue>* _dict)
- {
- this->dict = _dict;
- this->key = _Move(_key);
- }
- TValue& getValue() const
- {
- auto pos = dict->findPosition(key);
- if (pos.objectPosition != -1)
- {
- return dict->m_hashMap[pos.objectPosition]->value.value;
- }
- else
- {
- SLANG_ASSERT_FAILURE("The key does not exists in dictionary.");
- }
- }
- inline TValue& operator()() const { return getValue(); }
- operator TValue&() const { return getValue(); }
- TValue& operator=(const TValue& val)
- {
- return ((OrderedDictionary<TKey, TValue>*)dict)
- ->set(KeyValuePair<TKey, TValue>(_Move(key), val));
- }
- TValue& operator=(TValue&& val)
- {
- return ((OrderedDictionary<TKey, TValue>*)dict)
- ->set(KeyValuePair<TKey, TValue>(_Move(key), _Move(val)));
- }
- };
- ItemProxy operator[](const TKey& key) const { return ItemProxy(key, this); }
- ItemProxy operator[](TKey&& key) const { return ItemProxy(_Move(key), this); }
-
- int getCount() const { return m_count; }
- KeyValuePair<TKey, TValue>& getFirst() const { return m_kvPairs.getFirst(); }
- KeyValuePair<TKey, TValue>& getLast() const { return m_kvPairs.getLast(); }
-
- private:
- template <typename... Args>
- void init(const KeyValuePair<TKey, TValue>& kvPair, Args... args)
+ return &(m_hashMap[pos.objectPosition]->value.value);
+ }
+ return nullptr;
+ }
+ template<typename T>
+ bool tryGetValue(const T& key, TValue& value) const
+ {
+ if (m_bucketCountMinusOne == -1)
+ return false;
+ auto pos = findPosition(key);
+ if (pos.objectPosition != -1)
{
- add(kvPair);
- init(args...);
+ value = m_hashMap[pos.objectPosition]->value.value;
+ return true;
}
+ return false;
+ }
+ class ItemProxy
+ {
+ private:
+ const OrderedDictionary<TKey, TValue>* dict;
+ TKey key;
public:
- OrderedDictionary()
- {
- m_bucketCountMinusOne = -1;
- m_count = 0;
- m_hashMap = 0;
- }
- template <typename Arg, typename... Args> OrderedDictionary(Arg arg, Args... args)
+ ItemProxy(const TKey& _key, const OrderedDictionary<TKey, TValue>* _dict)
{
- init(arg, args...);
+ this->dict = _dict;
+ this->key = _key;
}
- OrderedDictionary(const OrderedDictionary<TKey, TValue>& other)
- : m_bucketCountMinusOne(-1)
- , m_count(0)
- , m_hashMap(0)
+ ItemProxy(TKey&& _key, const OrderedDictionary<TKey, TValue>* _dict)
{
- *this = other;
+ this->dict = _dict;
+ this->key = _Move(_key);
}
- OrderedDictionary(OrderedDictionary<TKey, TValue>&& other)
- : m_bucketCountMinusOne(-1)
- , m_count(0)
- , m_hashMap(0)
+ TValue& getValue() const
{
- *this = (_Move(other));
+ auto pos = dict->findPosition(key);
+ if (pos.objectPosition != -1)
+ {
+ return dict->m_hashMap[pos.objectPosition]->value.value;
+ }
+ else
+ {
+ SLANG_ASSERT_FAILURE("The key does not exists in dictionary.");
+ }
}
- OrderedDictionary<TKey, TValue>&
- operator=(const OrderedDictionary<TKey, TValue>& other)
+ inline TValue& operator()() const { return getValue(); }
+ operator TValue&() const { return getValue(); }
+ TValue& operator=(const TValue& val)
{
- if (this == &other)
- return *this;
- clear();
- for (auto& item : other)
- add(item.key, item.value);
- return *this;
+ return ((OrderedDictionary<TKey, TValue>*)dict)
+ ->set(KeyValuePair<TKey, TValue>(_Move(key), val));
}
- OrderedDictionary<TKey, TValue>&
- operator=(OrderedDictionary<TKey, TValue>&& other)
+ TValue& operator=(TValue&& val)
{
- if (this == &other)
- return *this;
- deallocateAll();
- m_bucketCountMinusOne = other.m_bucketCountMinusOne;
- m_count = other.m_count;
- m_hashMap = other.m_hashMap;
- m_marks = _Move(other.m_marks);
- other.m_hashMap = 0;
- other.m_count = 0;
- other.m_bucketCountMinusOne = -1;
- m_kvPairs = _Move(other.m_kvPairs);
- return *this;
+ return ((OrderedDictionary<TKey, TValue>*)dict)
+ ->set(KeyValuePair<TKey, TValue>(_Move(key), _Move(val)));
}
- ~OrderedDictionary() { deallocateAll(); }
};
+ ItemProxy operator[](const TKey& key) const { return ItemProxy(key, this); }
+ ItemProxy operator[](TKey&& key) const { return ItemProxy(_Move(key), this); }
- template <typename T> class OrderedHashSet : public HashSetBase<T, OrderedDictionary<T, _DummyClass>>
+ int getCount() const { return m_count; }
+ KeyValuePair<TKey, TValue>& getFirst() const { return m_kvPairs.getFirst(); }
+ KeyValuePair<TKey, TValue>& getLast() const { return m_kvPairs.getLast(); }
+
+private:
+ template<typename... Args>
+ void init(const KeyValuePair<TKey, TValue>& kvPair, Args... args)
{
- public:
- T& getLast()
- {
- return this->dict.getLast().key;
- }
- void removeLast()
- {
- this->remove(getLast());
- }
- };
-}
+ add(kvPair);
+ init(args...);
+ }
+
+public:
+ OrderedDictionary()
+ {
+ m_bucketCountMinusOne = -1;
+ m_count = 0;
+ m_hashMap = 0;
+ }
+ template<typename Arg, typename... Args>
+ OrderedDictionary(Arg arg, Args... args)
+ {
+ init(arg, args...);
+ }
+ OrderedDictionary(const OrderedDictionary<TKey, TValue>& other)
+ : m_bucketCountMinusOne(-1), m_count(0), m_hashMap(0)
+ {
+ *this = other;
+ }
+ OrderedDictionary(OrderedDictionary<TKey, TValue>&& other)
+ : m_bucketCountMinusOne(-1), m_count(0), m_hashMap(0)
+ {
+ *this = (_Move(other));
+ }
+ OrderedDictionary<TKey, TValue>& operator=(const OrderedDictionary<TKey, TValue>& other)
+ {
+ if (this == &other)
+ return *this;
+ clear();
+ for (auto& item : other)
+ add(item.key, item.value);
+ return *this;
+ }
+ OrderedDictionary<TKey, TValue>& operator=(OrderedDictionary<TKey, TValue>&& other)
+ {
+ if (this == &other)
+ return *this;
+ deallocateAll();
+ m_bucketCountMinusOne = other.m_bucketCountMinusOne;
+ m_count = other.m_count;
+ m_hashMap = other.m_hashMap;
+ m_marks = _Move(other.m_marks);
+ other.m_hashMap = 0;
+ other.m_count = 0;
+ other.m_bucketCountMinusOne = -1;
+ m_kvPairs = _Move(other.m_kvPairs);
+ return *this;
+ }
+ ~OrderedDictionary() { deallocateAll(); }
+};
+
+template<typename T>
+class OrderedHashSet : public HashSetBase<T, OrderedDictionary<T, _DummyClass>>
+{
+public:
+ T& getLast() { return this->dict.getLast().key; }
+ void removeLast() { this->remove(getLast()); }
+};
+} // namespace Slang
#endif
diff --git a/source/core/slang-exception.h b/source/core/slang-exception.h
index 3c5621d7f..654ce0156 100644
--- a/source/core/slang-exception.h
+++ b/source/core/slang-exception.h
@@ -6,61 +6,55 @@
namespace Slang
{
- // NOTE!
- // Exceptions should not generally be used in core/compiler-core, use the 'signal' mechanism
- // ideally using the macros in the slang-signal.h such as `SLANG_UNEXPECTED`
- //
- // If core/compiler-core libraries are compiled with SLANG_DISABLE_EXCEPTIONS,
- // these classes will *never* be thrown.
-
- class Exception
- {
- public:
- String Message;
- Exception()
- {}
- Exception(const String & message)
- : Message(message)
- {
- }
+// NOTE!
+// Exceptions should not generally be used in core/compiler-core, use the 'signal' mechanism
+// ideally using the macros in the slang-signal.h such as `SLANG_UNEXPECTED`
+//
+// If core/compiler-core libraries are compiled with SLANG_DISABLE_EXCEPTIONS,
+// these classes will *never* be thrown.
- virtual ~Exception()
- {}
- };
+class Exception
+{
+public:
+ String Message;
+ Exception() {}
+ Exception(const String& message)
+ : Message(message)
+ {
+ }
- class InvalidOperationException : public Exception
- {
- public:
- InvalidOperationException()
- {}
- InvalidOperationException(const String & message)
- : Exception(message)
- {
- }
+ virtual ~Exception() {}
+};
+
+class InvalidOperationException : public Exception
+{
+public:
+ InvalidOperationException() {}
+ InvalidOperationException(const String& message)
+ : Exception(message)
+ {
+ }
+};
- };
-
- class InternalError : public Exception
- {
- public:
- InternalError()
- {}
- InternalError(const String & message)
- : Exception(message)
- {
- }
- };
+class InternalError : public Exception
+{
+public:
+ InternalError() {}
+ InternalError(const String& message)
+ : Exception(message)
+ {
+ }
+};
- class AbortCompilationException : public Exception
+class AbortCompilationException : public Exception
+{
+public:
+ AbortCompilationException() {}
+ AbortCompilationException(const String& message)
+ : Exception(message)
{
- public:
- AbortCompilationException()
- {}
- AbortCompilationException(const String & message)
- : Exception(message)
- {
- }
- };
-}
+ }
+};
+} // namespace Slang
#endif
diff --git a/source/core/slang-file-system.cpp b/source/core/slang-file-system.cpp
index d578e63d5..3e129f7bf 100644
--- a/source/core/slang-file-system.cpp
+++ b/source/core/slang-file-system.cpp
@@ -1,19 +1,24 @@
#include "slang-file-system.h"
-#include "slang-com-ptr.h"
#include "../core/slang-io.h"
#include "../core/slang-string-util.h"
+#include "slang-com-ptr.h"
namespace Slang
{
-SLANG_FORCE_INLINE static SlangResult _checkExt(FileSystemStyle style) { return Index(style) >= Index(FileSystemStyle::Ext) ? SLANG_OK : SLANG_E_NOT_IMPLEMENTED; }
-SLANG_FORCE_INLINE static SlangResult _checkMutable(FileSystemStyle style) { return Index(style) >= Index(FileSystemStyle::Mutable) ? SLANG_OK : SLANG_E_NOT_IMPLEMENTED; }
+SLANG_FORCE_INLINE static SlangResult _checkExt(FileSystemStyle style)
+{
+ return Index(style) >= Index(FileSystemStyle::Ext) ? SLANG_OK : SLANG_E_NOT_IMPLEMENTED;
+}
+SLANG_FORCE_INLINE static SlangResult _checkMutable(FileSystemStyle style)
+{
+ return Index(style) >= Index(FileSystemStyle::Mutable) ? SLANG_OK : SLANG_E_NOT_IMPLEMENTED;
+}
SLANG_FORCE_INLINE static bool _canCast(FileSystemStyle style, const Guid& guid)
{
- if (guid == ISlangUnknown::getTypeGuid() ||
- guid == ISlangCastable::getTypeGuid() ||
+ if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangCastable::getTypeGuid() ||
guid == ISlangFileSystem::getTypeGuid())
{
return true;
@@ -35,11 +40,14 @@ static FileSystemStyle _getFileSystemStyle(ISlangFileSystem* system, ComPtr<ISla
FileSystemStyle style = FileSystemStyle::Load;
- if (SLANG_SUCCEEDED(system->queryInterface(ISlangMutableFileSystem::getTypeGuid(), (void**)out.writeRef())))
+ if (SLANG_SUCCEEDED(
+ system->queryInterface(ISlangMutableFileSystem::getTypeGuid(), (void**)out.writeRef())))
{
- style = FileSystemStyle::Mutable;
+ style = FileSystemStyle::Mutable;
}
- else if (SLANG_SUCCEEDED(system->queryInterface(ISlangFileSystemExt::getTypeGuid(), (void**)out.writeRef())))
+ else if (SLANG_SUCCEEDED(system->queryInterface(
+ ISlangFileSystemExt::getTypeGuid(),
+ (void**)out.writeRef())))
{
style = FileSystemStyle::Ext;
}
@@ -54,17 +62,21 @@ static FileSystemStyle _getFileSystemStyle(ISlangFileSystem* system, ComPtr<ISla
}
// Calcuate a combined path, just using Path:: string processing
-static SlangResult _calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
+static SlangResult _calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut)
{
String relPath;
switch (fromPathType)
{
- case SLANG_PATH_TYPE_FILE:
+ case SLANG_PATH_TYPE_FILE:
{
relPath = Path::combine(Path::getParentDirectory(fromPath), path);
break;
}
- case SLANG_PATH_TYPE_DIRECTORY:
+ case SLANG_PATH_TYPE_DIRECTORY:
{
relPath = Path::combine(fromPath, path);
break;
@@ -77,9 +89,9 @@ static SlangResult _calcCombinedPath(SlangPathType fromPathType, const char* fro
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! OSFileSystem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
-/* static */OSFileSystem OSFileSystem::g_load(FileSystemStyle::Load);
-/* static */OSFileSystem OSFileSystem::g_ext(FileSystemStyle::Ext);
-/* static */OSFileSystem OSFileSystem::g_mutable(FileSystemStyle::Mutable);
+/* static */ OSFileSystem OSFileSystem::g_load(FileSystemStyle::Load);
+/* static */ OSFileSystem OSFileSystem::g_ext(FileSystemStyle::Ext);
+/* static */ OSFileSystem OSFileSystem::g_mutable(FileSystemStyle::Mutable);
void* OSFileSystem::castAs(const Guid& guid)
{
@@ -126,8 +138,8 @@ SlangResult OSFileSystem::getPath(PathKind pathKind, const char* path, ISlangBlo
switch (pathKind)
{
- case PathKind::OperatingSystem:
- case PathKind::Display:
+ case PathKind::OperatingSystem:
+ case PathKind::Display:
{
// It's possible canonical path fail...
if (SLANG_SUCCEEDED(getPath(PathKind::Canonical, path, outPath)))
@@ -137,14 +149,14 @@ SlangResult OSFileSystem::getPath(PathKind pathKind, const char* path, ISlangBlo
// If so try simplified
return getPath(PathKind::Simplified, path, outPath);
}
- case PathKind::Canonical:
+ case PathKind::Canonical:
{
String canonicalPath;
SLANG_RETURN_ON_FAIL(Path::getCanonical(_fixPathDelimiters(path), canonicalPath));
*outPath = StringUtil::createStringBlob(canonicalPath).detach();
return SLANG_OK;
}
- case PathKind::Simplified:
+ case PathKind::Simplified:
{
String simplifiedPath = Path::simplify(path);
*outPath = StringUtil::createStringBlob(simplifiedPath).detach();
@@ -155,7 +167,11 @@ SlangResult OSFileSystem::getPath(PathKind pathKind, const char* path, ISlangBlo
return SLANG_E_NOT_AVAILABLE;
}
-SlangResult OSFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
+SlangResult OSFileSystem::calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut)
{
SLANG_RETURN_ON_FAIL(_checkExt(m_style));
@@ -173,7 +189,8 @@ SlangResult SLANG_MCALL OSFileSystem::getPathType(const char* pathIn, SlangPathT
SlangResult OSFileSystem::loadFile(char const* pathIn, ISlangBlob** outBlob)
{
- // Default implementation that uses the `core` libraries facilities for talking to the OS filesystem.
+ // Default implementation that uses the `core` libraries facilities for talking to the OS
+ // filesystem.
//
// TODO: we might want to conditionally compile these in, so that
// a user could create a build of Slang that doesn't include any OS
@@ -191,7 +208,10 @@ SlangResult OSFileSystem::loadFile(char const* pathIn, ISlangBlob** outBlob)
return SLANG_OK;
}
-SlangResult OSFileSystem::enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData)
+SlangResult OSFileSystem::enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData)
{
SLANG_RETURN_ON_FAIL(_checkExt(m_style));
@@ -205,17 +225,16 @@ SlangResult OSFileSystem::enumeratePathContents(const char* path, FileSystemCont
SlangPathType pathType;
switch (type)
{
- case Path::Type::File: pathType = SLANG_PATH_TYPE_FILE; break;
- case Path::Type::Directory: pathType = SLANG_PATH_TYPE_DIRECTORY; break;
- default: return;
+ case Path::Type::File: pathType = SLANG_PATH_TYPE_FILE; break;
+ case Path::Type::Directory: pathType = SLANG_PATH_TYPE_DIRECTORY; break;
+ default: return;
}
m_callback(pathType, m_buffer.getBuffer(), m_userData);
}
- Visitor(FileSystemContentsCallBack callback, void* userData) :
- m_callback(callback),
- m_userData(userData)
+ Visitor(FileSystemContentsCallBack callback, void* userData)
+ : m_callback(callback), m_userData(userData)
{
}
StringBuilder m_buffer;
@@ -234,7 +253,8 @@ SlangResult OSFileSystem::saveFile(const char* pathIn, const void* data, size_t
SLANG_RETURN_ON_FAIL(_checkMutable(m_style));
const String path = _fixPathDelimiters(pathIn);
FileStream stream;
- SLANG_RETURN_ON_FAIL(stream.init(pathIn, FileMode::Create, FileAccess::Write, FileShare::ReadWrite));
+ SLANG_RETURN_ON_FAIL(
+ stream.init(pathIn, FileMode::Create, FileAccess::Write, FileShare::ReadWrite));
SLANG_RETURN_ON_FAIL(stream.write(data, size));
return SLANG_OK;
}
@@ -262,16 +282,15 @@ SlangResult OSFileSystem::createDirectory(const char* path)
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CacheFileSystem !!!!!!!!!!!!!!!!!!!!!!!!!!!
-/* static */ const Result CacheFileSystem::s_compressedResultToResult[] =
-{
- SLANG_E_UNINITIALIZED,
- SLANG_OK, ///< Ok
- SLANG_E_NOT_FOUND, ///< File not found
- SLANG_E_CANNOT_OPEN, ///< CannotOpen,
- SLANG_FAIL, ///< Fail
+/* static */ const Result CacheFileSystem::s_compressedResultToResult[] = {
+ SLANG_E_UNINITIALIZED,
+ SLANG_OK, ///< Ok
+ SLANG_E_NOT_FOUND, ///< File not found
+ SLANG_E_CANNOT_OPEN, ///< CannotOpen,
+ SLANG_FAIL, ///< Fail
};
-/* static */CacheFileSystem::CompressedResult CacheFileSystem::toCompressedResult(Result res)
+/* static */ CacheFileSystem::CompressedResult CacheFileSystem::toCompressedResult(Result res)
{
if (SLANG_SUCCEEDED(res))
{
@@ -279,9 +298,9 @@ SlangResult OSFileSystem::createDirectory(const char* path)
}
switch (res)
{
- case SLANG_E_CANNOT_OPEN: return CompressedResult::CannotOpen;
- case SLANG_E_NOT_FOUND: return CompressedResult::NotFound;
- default: return CompressedResult::Fail;
+ case SLANG_E_CANNOT_OPEN: return CompressedResult::CannotOpen;
+ case SLANG_E_NOT_FOUND: return CompressedResult::NotFound;
+ default: return CompressedResult::Fail;
}
}
@@ -312,7 +331,10 @@ void* CacheFileSystem::getObject(const Guid& guid)
return nullptr;
}
-CacheFileSystem::CacheFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode, PathStyle pathStyle)
+CacheFileSystem::CacheFileSystem(
+ ISlangFileSystem* fileSystem,
+ UniqueIdentityMode uniqueIdentityMode,
+ PathStyle pathStyle)
{
setInnerFileSystem(fileSystem, uniqueIdentityMode, pathStyle);
}
@@ -323,13 +345,16 @@ CacheFileSystem::~CacheFileSystem()
delete pathInfo;
}
-void CacheFileSystem::setInnerFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode, PathStyle pathStyle)
+void CacheFileSystem::setInnerFileSystem(
+ ISlangFileSystem* fileSystem,
+ UniqueIdentityMode uniqueIdentityMode,
+ PathStyle pathStyle)
{
m_fileSystem = fileSystem;
m_uniqueIdentityMode = uniqueIdentityMode;
m_pathStyle = pathStyle;
-
+
m_fileSystemExt.setNull();
if (fileSystem)
@@ -343,19 +368,21 @@ void CacheFileSystem::setInnerFileSystem(ISlangFileSystem* fileSystem, UniqueIde
switch (m_uniqueIdentityMode)
{
- case UniqueIdentityMode::Default:
- case UniqueIdentityMode::FileSystemExt:
+ case UniqueIdentityMode::Default:
+ case UniqueIdentityMode::FileSystemExt:
{
- // If it's not a complete file system, we will default to SimplifyAndHash style by default
- m_uniqueIdentityMode = m_fileSystemExt ? UniqueIdentityMode::FileSystemExt : UniqueIdentityMode::SimplifyPathAndHash;
+ // If it's not a complete file system, we will default to SimplifyAndHash style by
+ // default
+ m_uniqueIdentityMode = m_fileSystemExt ? UniqueIdentityMode::FileSystemExt
+ : UniqueIdentityMode::SimplifyPathAndHash;
break;
}
- default: break;
+ default: break;
}
if (pathStyle == PathStyle::Default)
{
- // We'll assume it's simplify-able
+ // We'll assume it's simplify-able
m_pathStyle = PathStyle::Simplifiable;
// If we have fileSystemExt, we defer to that
if (m_fileSystemExt)
@@ -390,19 +417,22 @@ static bool _canSimplifyPath(CacheFileSystem::UniqueIdentityMode mode)
typedef CacheFileSystem::UniqueIdentityMode UniqueIdentityMode;
switch (mode)
{
- case UniqueIdentityMode::SimplifyPath:
- case UniqueIdentityMode::SimplifyPathAndHash:
+ case UniqueIdentityMode::SimplifyPath:
+ case UniqueIdentityMode::SimplifyPathAndHash:
{
return true;
}
- default:
+ default:
{
return false;
}
}
}
-SlangResult CacheFileSystem::enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData)
+SlangResult CacheFileSystem::enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData)
{
if (m_fileSystemExt)
{
@@ -430,8 +460,9 @@ SlangResult CacheFileSystem::enumeratePathContents(const char* path, FileSystemC
for (const auto& [currentPath, pathInfo] : m_pathMap)
{
- // NOTE! The currentPath can be a *non* simplified path (the m_pathMap is the cache of paths simplified and other to a file/directory)
- // Also note that there will always be the simplified version of the path in cache.
+ // NOTE! The currentPath can be a *non* simplified path (the m_pathMap is the cache of paths
+ // simplified and other to a file/directory) Also note that there will always be the
+ // simplified version of the path in cache.
// If it doesn't start with simplified path, then it can't be a hit
if (!currentPath.startsWith(simplifiedPath))
@@ -439,7 +470,9 @@ SlangResult CacheFileSystem::enumeratePathContents(const char* path, FileSystemC
continue;
}
- UnownedStringSlice remaining(currentPath.getBuffer() + simplifiedPath.getLength(), currentPath.end());
+ UnownedStringSlice remaining(
+ currentPath.getBuffer() + simplifiedPath.getLength(),
+ currentPath.end());
// If it starts with a / delimiter strip it
if (remaining.getLength() > 0 && remaining[0] == '/')
@@ -447,16 +480,17 @@ SlangResult CacheFileSystem::enumeratePathContents(const char* path, FileSystemC
remaining = UnownedStringSlice(remaining.begin() + 1, remaining.end());
}
- // If it has a path separator then it's either not simplified - so we ignore (we only want to invoke on the simplified path version as there is only one
- // of these for every PathInfo)
- // or it is a child file/directory, and so we ignore that too.
+ // If it has a path separator then it's either not simplified - so we ignore (we only want
+ // to invoke on the simplified path version as there is only one of these for every
+ // PathInfo) or it is a child file/directory, and so we ignore that too.
if (remaining.indexOf('/') >= 0 || remaining.indexOf('\\') >= 0)
{
continue;
}
- // We *know* that remaining comes from the end of currentPath .We also know currentPath is zero terminated.
- // So we can just use (normally this would be a problem because UnownedStringSlice is generally *not* followed by zero termination.
+ // We *know* that remaining comes from the end of currentPath .We also know currentPath is
+ // zero terminated. So we can just use (normally this would be a problem because
+ // UnownedStringSlice is generally *not* followed by zero termination.
const char* foundPath = remaining.begin();
// Let's check that fact...
SLANG_ASSERT(foundPath[remaining.getLength()] == 0);
@@ -474,35 +508,42 @@ SlangResult CacheFileSystem::enumeratePathContents(const char* path, FileSystemC
}
-SlangResult CacheFileSystem::_calcUniqueIdentity(const String& path, String& outUniqueIdentity, ComPtr<ISlangBlob>& outFileContents)
+SlangResult CacheFileSystem::_calcUniqueIdentity(
+ const String& path,
+ String& outUniqueIdentity,
+ ComPtr<ISlangBlob>& outFileContents)
{
switch (m_uniqueIdentityMode)
{
- case UniqueIdentityMode::FileSystemExt:
+ case UniqueIdentityMode::FileSystemExt:
{
// Try getting the uniqueIdentity by asking underlying file system
ComPtr<ISlangBlob> uniqueIdentity;
- SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(path.getBuffer(), uniqueIdentity.writeRef()));
+ SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(
+ path.getBuffer(),
+ uniqueIdentity.writeRef()));
// Get the path as a string
outUniqueIdentity = StringUtil::getString(uniqueIdentity);
return SLANG_OK;
}
- case UniqueIdentityMode::Path:
+ case UniqueIdentityMode::Path:
{
outUniqueIdentity = path;
return SLANG_OK;
}
- case UniqueIdentityMode::SimplifyPath:
+ case UniqueIdentityMode::SimplifyPath:
{
outUniqueIdentity = Path::simplify(path);
// If it still has relative elements can't uniquely identify, so give up
return Path::hasRelativeElement(outUniqueIdentity) ? SLANG_FAIL : SLANG_OK;
}
- case UniqueIdentityMode::SimplifyPathAndHash:
- case UniqueIdentityMode::Hash:
+ case UniqueIdentityMode::SimplifyPathAndHash:
+ case UniqueIdentityMode::Hash:
{
- // If m_uniqueIdentityMode is SimplifyPathAndHash, the path will already be simplified before this function is hit (and it hasn't been found
- // via path lookup). That being the case only option left is to 'hash' (or fallback to backing impls uniqueIdentity impl)
+ // If m_uniqueIdentityMode is SimplifyPathAndHash, the path will already be simplified
+ // before this function is hit (and it hasn't been found via path lookup). That being
+ // the case only option left is to 'hash' (or fallback to backing impls uniqueIdentity
+ // impl)
// If we don't have a file system -> assume cannot be found
if (m_fileSystem == nullptr)
@@ -519,27 +560,32 @@ SlangResult CacheFileSystem::_calcUniqueIdentity(const String& path, String& out
// If that failed, we may be able to do something if m_fileSystemExt is available
if (SLANG_FAILED(res))
{
- // If we have m_fileSystemExt interface we can just use it's implementation, as a fallback.
- // Doing so will mean the uniqueIdentity will work if say it's a directory
+ // If we have m_fileSystemExt interface we can just use it's implementation, as a
+ // fallback. Doing so will mean the uniqueIdentity will work if say it's a directory
if (m_fileSystemExt)
{
ComPtr<ISlangBlob> uniqueIdentity;
- SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(path.getBuffer(), uniqueIdentity.writeRef()));
+ SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(
+ path.getBuffer(),
+ uniqueIdentity.writeRef()));
// Get the path as a string
outUniqueIdentity = StringUtil::getString(uniqueIdentity);
return SLANG_OK;
}
-
- // If we can't access as a file (or use the backing implementations impl), we are in a tricky situation.
- // The ISlangFileSystem interface provides no way to determine if the path is a directory for example -
- // so there is no way of determining if something along the path exists.
- //
+
+ // If we can't access as a file (or use the backing implementations impl), we are in
+ // a tricky situation. The ISlangFileSystem interface provides no way to determine
+ // if the path is a directory for example - so there is no way of determining if
+ // something along the path exists.
+ //
// So we just return the error.
return res;
}
-
+
// Calculate the hash on the contents
- const StableHashCode64 hash = getStableHashCode64((const char*)outFileContents->getBufferPointer(), outFileContents->getBufferSize());
+ const StableHashCode64 hash = getStableHashCode64(
+ (const char*)outFileContents->getBufferPointer(),
+ outFileContents->getBufferSize());
String hashString = Path::getFileName(path);
hashString = hashString.toLower();
@@ -582,8 +628,8 @@ CacheFileSystem::PathInfo* CacheFileSystem::_resolveUniqueIdentityCacheInfo(cons
// At this point they must have same uniqueIdentity
SLANG_ASSERT(pathInfo->getUniqueIdentity() == uniqueIdentity);
- // If we have the file contents (because of calc-ing uniqueIdentity), and there isn't a read file blob already
- // store the data as if read, so doesn't get read again
+ // If we have the file contents (because of calc-ing uniqueIdentity), and there isn't a read
+ // file blob already store the data as if read, so doesn't get read again
if (fileContents && !pathInfo->m_fileBlob)
{
pathInfo->m_fileBlob = fileContents;
@@ -595,7 +641,8 @@ CacheFileSystem::PathInfo* CacheFileSystem::_resolveUniqueIdentityCacheInfo(cons
CacheFileSystem::PathInfo* CacheFileSystem::_resolveSimplifiedPathCacheInfo(const String& path)
{
- // If we can simplify the path, try looking up in path cache with simplified path (as long as it's different!)
+ // If we can simplify the path, try looking up in path cache with simplified path (as long as
+ // it's different!)
if (_canSimplifyPath(m_uniqueIdentityMode))
{
const String simplifiedPath = Path::simplify(path);
@@ -607,7 +654,7 @@ CacheFileSystem::PathInfo* CacheFileSystem::_resolveSimplifiedPathCacheInfo(cons
}
}
- return _resolveUniqueIdentityCacheInfo(path);
+ return _resolveUniqueIdentityCacheInfo(path);
}
CacheFileSystem::PathInfo* CacheFileSystem::_resolvePathCacheInfo(const String& path)
@@ -636,10 +683,11 @@ SlangResult CacheFileSystem::loadFile(char const* pathIn, ISlangBlob** blobOut)
{
return SLANG_FAIL;
}
-
+
if (info->m_loadFileResult == CompressedResult::Uninitialized)
{
- info->m_loadFileResult = toCompressedResult(m_fileSystem->loadFile(path.getBuffer(), info->m_fileBlob.writeRef()));
+ info->m_loadFileResult = toCompressedResult(
+ m_fileSystem->loadFile(path.getBuffer(), info->m_fileBlob.writeRef()));
}
*blobOut = info->m_fileBlob;
@@ -663,16 +711,20 @@ SlangResult CacheFileSystem::getFileUniqueIdentity(const char* path, ISlangBlob*
return SLANG_OK;
}
-SlangResult CacheFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
+SlangResult CacheFileSystem::calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut)
{
// Just defer to contained implementation
switch (m_pathStyle)
{
- case PathStyle::FileSystemExt:
+ case PathStyle::FileSystemExt:
{
return m_fileSystemExt->calcCombinedPath(fromPathType, fromPath, path, pathOut);
}
- default:
+ default:
{
// Just use the default implementation
return _calcCombinedPath(fromPathType, fromPath, path, pathOut);
@@ -680,20 +732,25 @@ SlangResult CacheFileSystem::calcCombinedPath(SlangPathType fromPathType, const
}
}
-SlangResult CacheFileSystem::_getPathType(PathInfo* info, const char* inPath, SlangPathType* outPathType)
+SlangResult CacheFileSystem::_getPathType(
+ PathInfo* info,
+ const char* inPath,
+ SlangPathType* outPathType)
{
if (info->m_getPathTypeResult == CompressedResult::Uninitialized)
{
if (m_fileSystemExt)
{
- info->m_getPathTypeResult = toCompressedResult(m_fileSystemExt->getPathType(inPath, &info->m_pathType));
+ info->m_getPathTypeResult =
+ toCompressedResult(m_fileSystemExt->getPathType(inPath, &info->m_pathType));
}
else
{
// Okay try to load the file
if (info->m_loadFileResult == CompressedResult::Uninitialized)
{
- info->m_loadFileResult = toCompressedResult(m_fileSystem->loadFile(inPath, info->m_fileBlob.writeRef()));
+ info->m_loadFileResult =
+ toCompressedResult(m_fileSystem->loadFile(inPath, info->m_fileBlob.writeRef()));
}
// Make the getPathResult the same as the load result
@@ -722,9 +779,9 @@ SlangResult CacheFileSystem::getPath(PathKind kind, const char* path, ISlangBlob
{
switch (kind)
{
- case PathKind::Simplified: return _getSimplifiedPath(path, outPath);
- case PathKind::Canonical: return _getCanonicalPath(path, outPath);
- default: break;
+ case PathKind::Simplified: return _getSimplifiedPath(path, outPath);
+ case PathKind::Canonical: return _getCanonicalPath(path, outPath);
+ default: break;
}
if (m_fileSystemExt)
@@ -746,17 +803,17 @@ SlangResult CacheFileSystem::_getSimplifiedPath(const char* path, ISlangBlob** o
// If we have a ISlangFileSystemExt we can just pass on the request to it
switch (m_pathStyle)
{
- case PathStyle::FileSystemExt:
+ case PathStyle::FileSystemExt:
{
return m_fileSystemExt->getPath(PathKind::Simplified, path, outSimplifiedPath);
}
- case PathStyle::Simplifiable:
+ case PathStyle::Simplifiable:
{
String simplifiedPath = Path::simplify(path);
*outSimplifiedPath = StringUtil::createStringBlob(simplifiedPath).detach();
return SLANG_OK;
}
- default: return SLANG_E_NOT_IMPLEMENTED;
+ default: return SLANG_E_NOT_IMPLEMENTED;
}
}
@@ -764,7 +821,7 @@ SlangResult CacheFileSystem::_getCanonicalPath(const char* path, ISlangBlob** ou
{
*outCanonicalPath = nullptr;
- // A file must exist to get a canonical path...
+ // A file must exist to get a canonical path...
PathInfo* info = _resolvePathCacheInfo(path);
if (!info)
{
@@ -781,7 +838,8 @@ SlangResult CacheFileSystem::_getCanonicalPath(const char* path, ISlangBlob** ou
// Try getting the canonicalPath by asking underlying file system
ComPtr<ISlangBlob> canonicalPathBlob;
- SlangResult res = m_fileSystemExt->getPath(PathKind::Canonical, path, canonicalPathBlob.writeRef());
+ SlangResult res =
+ m_fileSystemExt->getPath(PathKind::Canonical, path, canonicalPathBlob.writeRef());
if (SLANG_SUCCEEDED(res))
{
@@ -808,9 +866,11 @@ SlangResult CacheFileSystem::_getCanonicalPath(const char* path, ISlangBlob** ou
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RelativeFileSystem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-RelativeFileSystem::RelativeFileSystem(ISlangFileSystem* fileSystem, const String& relativePath, bool stripPath) :
- m_relativePath(relativePath),
- m_stripPath(stripPath)
+RelativeFileSystem::RelativeFileSystem(
+ ISlangFileSystem* fileSystem,
+ const String& relativePath,
+ bool stripPath)
+ : m_relativePath(relativePath), m_stripPath(stripPath)
{
m_style = _getFileSystemStyle(fileSystem, m_fileSystem);
@@ -849,7 +909,11 @@ void* RelativeFileSystem::castAs(const Guid& guid)
return getObject(guid);
}
-SlangResult RelativeFileSystem::_calcCombinedPathInner(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** outPath)
+SlangResult RelativeFileSystem::_calcCombinedPathInner(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** outPath)
{
ISlangFileSystemExt* fileSystem = _getExt();
if (fileSystem)
@@ -866,14 +930,15 @@ SlangResult RelativeFileSystem::_getCanonicalPath(const char* path, String& outP
{
if (m_stripPath)
{
- // We are just using the filename. There is no path that could go outside of the the relative path so we can use as is
+ // We are just using the filename. There is no path that could go outside of the the
+ // relative path so we can use as is
outPath = Path::getFileName(path);
}
else
{
// NOTE that we don't want the canonical path to be absolute with a leading "/"
// because paths specified which aren't absolute, would produce a different path.
- //
+ //
// Ie we want (and get with these options)
// "a" -> "a"
// "/a" -> "a".
@@ -881,15 +946,16 @@ SlangResult RelativeFileSystem::_getCanonicalPath(const char* path, String& outP
// If we allowed the root to be included then...
// "a" -> "a"
// "/a" -> "/a"
- //
+ //
// Two identical paths would match to different paths, which wouldn't be canonical.
- //
- // This could be fixed by making all paths absolute with '/' too, but it's easier to just make all not
- // have "/"
+ //
+ // This could be fixed by making all paths absolute with '/' too, but it's easier to just
+ // make all not have "/"
StringBuilder canonicalPath;
// We want the input path to be local to this file system
- SLANG_RETURN_ON_FAIL(Path::simplify(path, Path::SimplifyStyle::AbsoluteOnlyAndNoRoot, canonicalPath));
+ SLANG_RETURN_ON_FAIL(
+ Path::simplify(path, Path::SimplifyStyle::AbsoluteOnlyAndNoRoot, canonicalPath));
outPath = canonicalPath;
}
return SLANG_OK;
@@ -901,10 +967,14 @@ SlangResult RelativeFileSystem::_getFixedPath(const char* path, String& outPath)
String canonicalPath;
SLANG_RETURN_ON_FAIL(_getCanonicalPath(path, canonicalPath));
-
- SLANG_RETURN_ON_FAIL(_calcCombinedPathInner(SLANG_PATH_TYPE_DIRECTORY, m_relativePath.getBuffer(), canonicalPath.getBuffer(), blob.writeRef()));
+
+ SLANG_RETURN_ON_FAIL(_calcCombinedPathInner(
+ SLANG_PATH_TYPE_DIRECTORY,
+ m_relativePath.getBuffer(),
+ canonicalPath.getBuffer(),
+ blob.writeRef()));
outPath = StringUtil::getString(blob);
-
+
return SLANG_OK;
}
@@ -915,20 +985,28 @@ SlangResult RelativeFileSystem::loadFile(char const* path, ISlangBlob** outBlob)
return m_fileSystem->loadFile(fixedPath.getBuffer(), outBlob);
}
-SlangResult RelativeFileSystem::getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity)
+SlangResult RelativeFileSystem::getFileUniqueIdentity(
+ const char* path,
+ ISlangBlob** outUniqueIdentity)
{
auto fileSystem = _getExt();
- if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED;
+ if (!fileSystem)
+ return SLANG_E_NOT_IMPLEMENTED;
String fixedPath;
SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath));
return fileSystem->getFileUniqueIdentity(fixedPath.getBuffer(), outUniqueIdentity);
}
-SlangResult RelativeFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** outPath)
+SlangResult RelativeFileSystem::calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** outPath)
{
auto fileSystem = _getExt();
- if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED;
+ if (!fileSystem)
+ return SLANG_E_NOT_IMPLEMENTED;
String fixedFromPath;
SLANG_RETURN_ON_FAIL(_getFixedPath(fromPath, fixedFromPath));
@@ -939,7 +1017,8 @@ SlangResult RelativeFileSystem::calcCombinedPath(SlangPathType fromPathType, con
SlangResult RelativeFileSystem::getPathType(const char* path, SlangPathType* outPathType)
{
auto fileSystem = _getExt();
- if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED;
+ if (!fileSystem)
+ return SLANG_E_NOT_IMPLEMENTED;
String fixedPath;
SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath));
@@ -949,28 +1028,30 @@ SlangResult RelativeFileSystem::getPathType(const char* path, SlangPathType* out
SlangResult RelativeFileSystem::getPath(PathKind kind, const char* path, ISlangBlob** outPath)
{
auto fileSystem = _getExt();
- if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED;
-
+ if (!fileSystem)
+ return SLANG_E_NOT_IMPLEMENTED;
+
switch (kind)
{
- case PathKind::Simplified:
+ case PathKind::Simplified:
{
return fileSystem->getPath(kind, path, outPath);
}
- case PathKind::Display:
+ case PathKind::Display:
{
// If not backed by OS, just use simplified path, else use the Operating system path
- kind = (fileSystem->getOSPathKind() == OSPathKind::None) ? PathKind::Simplified : PathKind::OperatingSystem;
+ kind = (fileSystem->getOSPathKind() == OSPathKind::None) ? PathKind::Simplified
+ : PathKind::OperatingSystem;
return getPath(kind, path, outPath);
}
- case PathKind::Canonical:
- {
+ case PathKind::Canonical:
+ {
String canonicalPath;
- SLANG_RETURN_ON_FAIL(_getCanonicalPath(path, canonicalPath));
+ SLANG_RETURN_ON_FAIL(_getCanonicalPath(path, canonicalPath));
*outPath = StringBlob::moveCreate(canonicalPath).detach();
return SLANG_OK;
}
- case PathKind::OperatingSystem:
+ case PathKind::OperatingSystem:
{
String fixedPath;
SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath));
@@ -984,15 +1065,20 @@ SlangResult RelativeFileSystem::getPath(PathKind kind, const char* path, ISlangB
void RelativeFileSystem::clearCache()
{
auto fileSystem = _getExt();
- if (!fileSystem) return;
+ if (!fileSystem)
+ return;
fileSystem->clearCache();
}
-SlangResult RelativeFileSystem::enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData)
+SlangResult RelativeFileSystem::enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData)
{
auto fileSystem = _getExt();
- if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED;
+ if (!fileSystem)
+ return SLANG_E_NOT_IMPLEMENTED;
String fixedPath;
SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath));
@@ -1002,7 +1088,8 @@ SlangResult RelativeFileSystem::enumeratePathContents(const char* path, FileSyst
SlangResult RelativeFileSystem::saveFile(const char* path, const void* data, size_t size)
{
auto fileSystem = _getMutable();
- if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED;
+ if (!fileSystem)
+ return SLANG_E_NOT_IMPLEMENTED;
String fixedPath;
SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath));
@@ -1012,8 +1099,9 @@ SlangResult RelativeFileSystem::saveFile(const char* path, const void* data, siz
SlangResult RelativeFileSystem::saveFileBlob(const char* path, ISlangBlob* dataBlob)
{
auto fileSystem = _getMutable();
- if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED;
-
+ if (!fileSystem)
+ return SLANG_E_NOT_IMPLEMENTED;
+
String fixedPath;
SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath));
return fileSystem->saveFileBlob(fixedPath.getBuffer(), dataBlob);
@@ -1022,7 +1110,8 @@ SlangResult RelativeFileSystem::saveFileBlob(const char* path, ISlangBlob* dataB
SlangResult RelativeFileSystem::remove(const char* path)
{
auto fileSystem = _getMutable();
- if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED;
+ if (!fileSystem)
+ return SLANG_E_NOT_IMPLEMENTED;
String fixedPath;
SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath));
@@ -1032,11 +1121,12 @@ SlangResult RelativeFileSystem::remove(const char* path)
SlangResult RelativeFileSystem::createDirectory(const char* path)
{
auto fileSystem = _getMutable();
- if (!fileSystem) return SLANG_E_NOT_IMPLEMENTED;
+ if (!fileSystem)
+ return SLANG_E_NOT_IMPLEMENTED;
String fixedPath;
SLANG_RETURN_ON_FAIL(_getFixedPath(path, fixedPath));
return fileSystem->createDirectory(fixedPath.getBuffer());
}
-}
+} // namespace Slang
diff --git a/source/core/slang-file-system.h b/source/core/slang-file-system.h
index dad2731d9..7ed500eb9 100644
--- a/source/core/slang-file-system.h
+++ b/source/core/slang-file-system.h
@@ -1,67 +1,81 @@
#ifndef SLANG_FILE_SYSTEM_H_INCLUDED
#define SLANG_FILE_SYSTEM_H_INCLUDED
-#include "slang.h"
-#include "slang-com-helper.h"
-#include "slang-com-ptr.h"
-
#include "../core/slang-blob.h"
-
-#include "../core/slang-string-util.h"
#include "../core/slang-dictionary.h"
+#include "../core/slang-string-util.h"
+#include "slang-com-helper.h"
+#include "slang-com-ptr.h"
+#include "slang.h"
namespace Slang
{
enum class FileSystemStyle
{
- Load, ///< Equivalent to ISlangFileSystem
- Ext, ///< Equivalent to ISlangFileSystemExt
- Mutable, ///< Equivalent to ISlangModifyableFileSystem
+ Load, ///< Equivalent to ISlangFileSystem
+ Ext, ///< Equivalent to ISlangFileSystemExt
+ Mutable, ///< Equivalent to ISlangModifyableFileSystem
};
// Can be used for all styles of file system
class OSFileSystem : public ISlangMutableFileSystem
{
public:
- // ISlangUnknown
+ // ISlangUnknown
// override ref counting, as DefaultFileSystem is singleton
- SLANG_IUNKNOWN_QUERY_INTERFACE
+ SLANG_IUNKNOWN_QUERY_INTERFACE
SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
- SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
// ISlangCastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// ISlangFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob)
+ SLANG_OVERRIDE;
// ISlangFileSystemExt
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getFileUniqueIdentity(const char* path, ISlangBlob** uniqueIdentityOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPathType(const char* path, SlangPathType* pathTypeOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getFileUniqueIdentity(const char* path, ISlangBlob** uniqueIdentityOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPathType(const char* path, SlangPathType* pathTypeOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL clearCache() SLANG_OVERRIDE {}
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE { return OSPathKind::Direct; }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE
+ {
+ return OSPathKind::Direct;
+ }
// ISlangModifyableFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL remove(const char* path) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL createDirectory(const char* path) SLANG_OVERRIDE;
- /// Get a default instance
+ /// Get a default instance
static ISlangFileSystem* getLoadSingleton() { return &g_load; }
static ISlangFileSystemExt* getExtSingleton() { return &g_ext; }
static ISlangMutableFileSystem* getMutableSingleton() { return &g_mutable; }
private:
-
/// Make so not constructible
- OSFileSystem(FileSystemStyle style):
- m_style(style)
- {}
+ OSFileSystem(FileSystemStyle style)
+ : m_style(style)
+ {
+ }
virtual ~OSFileSystem() {}
@@ -75,51 +89,52 @@ private:
static OSFileSystem g_mutable;
};
-/* Wraps an underlying ISlangFileSystem or ISlangFileSystemExt and provides caching,
+/* Wraps an underlying ISlangFileSystem or ISlangFileSystemExt and provides caching,
as well as emulation of methods if only has ISlangFileSystem interface. Will query capabilities
of the interface on the constructor.
-NOTE! That this behavior is the same as previously in that....
-1) calcRelativePath, just returns the path as processed by the Path:: methods
+NOTE! That this behavior is the same as previously in that....
+1) calcRelativePath, just returns the path as processed by the Path:: methods
2) getUniqueIdentity behavior depends on the UniqueIdentityMode.
*/
-class CacheFileSystem: public ISlangFileSystemExt, public ComBaseObject
+class CacheFileSystem : public ISlangFileSystemExt, public ComBaseObject
{
- public:
- SLANG_CLASS_GUID(0x2f4d1d03, 0xa0d1, 0x434b, { 0x87, 0x7a, 0x65, 0x5, 0xa4, 0xa0, 0x9a, 0x3b })
+public:
+ SLANG_CLASS_GUID(0x2f4d1d03, 0xa0d1, 0x434b, {0x87, 0x7a, 0x65, 0x5, 0xa4, 0xa0, 0x9a, 0x3b})
enum class PathStyle
{
- Default, ///< Pass to say use the default
- Simplifiable, ///< It can be simplified by Path::Simplify
- FileSystemExt, ///< Use file system
+ Default, ///< Pass to say use the default
+ Simplifiable, ///< It can be simplified by Path::Simplify
+ FileSystemExt, ///< Use file system
};
enum UniqueIdentityMode
{
- Default, ///< If passed, will default to the others depending on what kind of ISlangFileSystem is passed in
- Path, ///< Just use the path as is (old style slang behavior)
- SimplifyPath, ///< Use the input path 'simplified' (ie removing . and .. aspects)
- Hash, ///< Use hashing
- SimplifyPathAndHash, ///< Tries simplifying path first, and if that doesn't work it hashes
- FileSystemExt, ///< Use the file system extended interface.
+ Default, ///< If passed, will default to the others depending on what kind of
+ ///< ISlangFileSystem is passed in
+ Path, ///< Just use the path as is (old style slang behavior)
+ SimplifyPath, ///< Use the input path 'simplified' (ie removing . and .. aspects)
+ Hash, ///< Use hashing
+ SimplifyPathAndHash, ///< Tries simplifying path first, and if that doesn't work it hashes
+ FileSystemExt, ///< Use the file system extended interface.
};
/* Cannot change order/add members without changing s_compressedResultToResult */
- enum class CompressedResult: uint8_t
- {
- Uninitialized, ///< Holds no value
- Ok, ///< Ok
- NotFound, ///< File not found
- CannotOpen, ///< Cannot open
- Fail, ///< Generic failure
+ enum class CompressedResult : uint8_t
+ {
+ Uninitialized, ///< Holds no value
+ Ok, ///< Ok
+ NotFound, ///< File not found
+ CannotOpen, ///< Cannot open
+ Fail, ///< Generic failure
CountOf,
};
struct PathInfo
{
- PathInfo(const String& uniqueIdentity):
- m_uniqueIdentity(uniqueIdentity)
+ PathInfo(const String& uniqueIdentity)
+ : m_uniqueIdentity(uniqueIdentity)
{
m_loadFileResult = CompressedResult::Uninitialized;
m_getPathTypeResult = CompressedResult::Uninitialized;
@@ -151,72 +166,106 @@ class CacheFileSystem: public ISlangFileSystemExt, public ComBaseObject
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// ISlangFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob)
+ SLANG_OVERRIDE;
// ISlangFileSystemExt
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPathType(const char* path, SlangPathType* outPathType) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPath(PathKind kind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPathType(const char* path, SlangPathType* outPathType) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPath(PathKind kind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL clearCache() SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE { return m_osPathKind; }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE
+ {
+ return m_osPathKind;
+ }
- /// Get the unique identity mode
+ /// Get the unique identity mode
UniqueIdentityMode getUniqueIdentityMode() const { return m_uniqueIdentityMode; }
- /// Get the path style
+ /// Get the path style
PathStyle getPathStyle() const { return m_pathStyle; }
- /// Set the inner file system
- void setInnerFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default, PathStyle pathStyle = PathStyle::Default);
-
- /// Ctor
- explicit CacheFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default, PathStyle pathStyle = PathStyle::Default);
- /// Dtor
+ /// Set the inner file system
+ void setInnerFileSystem(
+ ISlangFileSystem* fileSystem,
+ UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default,
+ PathStyle pathStyle = PathStyle::Default);
+
+ /// Ctor
+ explicit CacheFileSystem(
+ ISlangFileSystem* fileSystem,
+ UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default,
+ PathStyle pathStyle = PathStyle::Default);
+ /// Dtor
virtual ~CacheFileSystem();
static CompressedResult toCompressedResult(Result res);
- static Result toResult(CompressedResult compRes) { return s_compressedResultToResult[int(compRes)]; }
+ static Result toResult(CompressedResult compRes)
+ {
+ return s_compressedResultToResult[int(compRes)];
+ }
static const Result s_compressedResultToResult[int(CompressedResult::CountOf)];
protected:
-
void* getInterface(const Guid& guid);
void* getObject(const Guid& guid);
SlangResult _getSimplifiedPath(const char* path, ISlangBlob** outSimplifiedPath);
SlangResult _getCanonicalPath(const char* path, ISlangBlob** outCanonicalPath);
- /// Given a path, works out a uniqueIdentity, based on the uniqueIdentityMode.
- /// outFileContents will be set if file had to be read to produce the uniqueIdentity (ie with Hash)
- /// If the file doesn't have to be read, then outFileContents will be nullptr, even if it is backed by a file.
- SlangResult _calcUniqueIdentity(const String& path, String& outUniqueIdentity, ComPtr<ISlangBlob>& outFileContents);
-
- /// For a given path gets a PathInfo. Can return nullptr, if it is not possible to create the PathInfo for some reason
+ /// Given a path, works out a uniqueIdentity, based on the uniqueIdentityMode.
+ /// outFileContents will be set if file had to be read to produce the uniqueIdentity (ie with
+ /// Hash) If the file doesn't have to be read, then outFileContents will be nullptr, even if it
+ /// is backed by a file.
+ SlangResult _calcUniqueIdentity(
+ const String& path,
+ String& outUniqueIdentity,
+ ComPtr<ISlangBlob>& outFileContents);
+
+ /// For a given path gets a PathInfo. Can return nullptr, if it is not possible to create the
+ /// PathInfo for some reason
PathInfo* _resolvePathCacheInfo(const String& path);
- /// Turns the path into a uniqueIdentity, and then tries to look up in the uniqueIdentityMap.
+ /// Turns the path into a uniqueIdentity, and then tries to look up in the uniqueIdentityMap.
PathInfo* _resolveUniqueIdentityCacheInfo(const String& path);
- /// Will simplify the path (if possible) to lookup on the pathCache else will create on uniqueIdentityMap
+ /// Will simplify the path (if possible) to lookup on the pathCache else will create on
+ /// uniqueIdentityMap
PathInfo* _resolveSimplifiedPathCacheInfo(const String& path);
SlangResult _getPathType(PathInfo* pathInfo, const char* inPath, SlangPathType* pathTypeOut);
- /* TODO: This may be improved by mapping to a ISlangBlob. This makes output fast and easy, and if constructed
- as a StringBlob, we can just static_cast to get as a string to use internally, instead of constantly converting.
- It is probably the case we cannot do dynamic_cast on ISlangBlob if we don't know where constructed -> if outside of slang codebase
- doing such a cast can cause an exception. So we *never* want to do dynamic cast from blobs which could be created by external code. */
+ /* TODO: This may be improved by mapping to a ISlangBlob. This makes output fast and easy, and
+ if constructed as a StringBlob, we can just static_cast to get as a string to use internally,
+ instead of constantly converting. It is probably the case we cannot do dynamic_cast on
+ ISlangBlob if we don't know where constructed -> if outside of slang codebase doing such a cast
+ can cause an exception. So we *never* want to do dynamic cast from blobs which could be created
+ by external code. */
- Dictionary<String, PathInfo*> m_pathMap; ///< Maps a path to a PathInfo (and unique identity)
- Dictionary<String, PathInfo*> m_uniqueIdentityMap; ///< Maps a unique identity for a file to its contents. This OWNs the PathInfo.
+ Dictionary<String, PathInfo*> m_pathMap; ///< Maps a path to a PathInfo (and unique identity)
+ Dictionary<String, PathInfo*> m_uniqueIdentityMap; ///< Maps a unique identity for a file to its
+ ///< contents. This OWNs the PathInfo.
- UniqueIdentityMode m_uniqueIdentityMode; ///< Determines how the 'uniqueIdentity' is produced. Cannot be Default in usage.
- PathStyle m_pathStyle; ///< Style of paths
+ UniqueIdentityMode m_uniqueIdentityMode; ///< Determines how the 'uniqueIdentity' is produced.
+ ///< Cannot be Default in usage.
+ PathStyle m_pathStyle; ///< Style of paths
- ComPtr<ISlangFileSystem> m_fileSystem; ///< Must always be set
- ComPtr<ISlangFileSystemExt> m_fileSystemExt; ///< Optionally set -> if nullptr will fall back on the m_fileSystem and emulate all the other methods of ISlangFileSystemExt
+ ComPtr<ISlangFileSystem> m_fileSystem; ///< Must always be set
+ ComPtr<ISlangFileSystemExt>
+ m_fileSystemExt; ///< Optionally set -> if nullptr will fall back on the m_fileSystem and
+ ///< emulate all the other methods of ISlangFileSystemExt
- OSPathKind m_osPathKind = OSPathKind::None; ///< OS path kind
+ OSPathKind m_osPathKind = OSPathKind::None; ///< OS path kind
};
class RelativeFileSystem : public ISlangMutableFileSystem, public ComBaseObject
@@ -225,54 +274,88 @@ public:
SLANG_COM_BASE_IUNKNOWN_ALL
// ISlangFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob)
+ SLANG_OVERRIDE;
// ISlangCastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// ISlangFileSystemExt
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPathType(const char* path, SlangPathType* outPathType) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPathType(const char* path, SlangPathType* outPathType) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL clearCache() SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE { return m_osPathKind; }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE
+ {
+ return m_osPathKind;
+ }
// ISlangModifyableFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL remove(const char* path) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL createDirectory(const char* path) SLANG_OVERRIDE;
- /// stripPath will remove any path for an access, making an access always just
- /// access the *filename* from the input path, in the contained filesystem at the relative path
- RelativeFileSystem(ISlangFileSystem* fileSystem, const String& relativePath, bool stripPath = false);
+ /// stripPath will remove any path for an access, making an access always just
+ /// access the *filename* from the input path, in the contained filesystem at the relative path
+ RelativeFileSystem(
+ ISlangFileSystem* fileSystem,
+ const String& relativePath,
+ bool stripPath = false);
protected:
-
- ISlangFileSystemExt* _getExt() { return Index(m_style) >= Index(FileSystemStyle::Ext) ? reinterpret_cast<ISlangFileSystemExt*>(m_fileSystem.get()) : nullptr; }
- ISlangMutableFileSystem* _getMutable() { return Index(m_style) >= Index(FileSystemStyle::Mutable) ? reinterpret_cast<ISlangMutableFileSystem*>(m_fileSystem.get()) : nullptr; }
-
- SlangResult _calcCombinedPathInner(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut);
-
- /// Get the fixed path to the item for the backing file system.
+ ISlangFileSystemExt* _getExt()
+ {
+ return Index(m_style) >= Index(FileSystemStyle::Ext)
+ ? reinterpret_cast<ISlangFileSystemExt*>(m_fileSystem.get())
+ : nullptr;
+ }
+ ISlangMutableFileSystem* _getMutable()
+ {
+ return Index(m_style) >= Index(FileSystemStyle::Mutable)
+ ? reinterpret_cast<ISlangMutableFileSystem*>(m_fileSystem.get())
+ : nullptr;
+ }
+
+ SlangResult _calcCombinedPathInner(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut);
+
+ /// Get the fixed path to the item for the backing file system.
SlangResult _getFixedPath(const char* path, String& outPath);
-
+
SlangResult _getCanonicalPath(const char* path, String& outPath);
ISlangUnknown* getInterface(const Guid& guid);
void* getObject(const Guid& guid);
- bool m_stripPath; ///< If set any path prior to an item will be stripped (making the directory in effect flat)
+ bool m_stripPath; ///< If set any path prior to an item will be stripped (making the directory
+ ///< in effect flat)
FileSystemStyle m_style;
- ComPtr<ISlangFileSystem> m_fileSystem; ///< NOTE! Has to match what's in style, such style can be reached via reinterpret_cast
+ ComPtr<ISlangFileSystem> m_fileSystem; ///< NOTE! Has to match what's in style, such style can
+ ///< be reached via reinterpret_cast
String m_relativePath;
- OSPathKind m_osPathKind = OSPathKind::None; ///< OS path kind
+ OSPathKind m_osPathKind = OSPathKind::None; ///< OS path kind
};
-}
+} // namespace Slang
#endif // SLANG_FILE_SYSTEM_H_INCLUDED
diff --git a/source/core/slang-free-list.cpp b/source/core/slang-free-list.cpp
index d364b548c..215004a74 100644
--- a/source/core/slang-free-list.cpp
+++ b/source/core/slang-free-list.cpp
@@ -1,232 +1,232 @@
#include "slang-free-list.h"
-//#include "list.h"
+// #include "list.h"
-namespace Slang {
+namespace Slang
+{
FreeList::~FreeList()
{
- _deallocateBlocks(m_activeBlocks);
- _deallocateBlocks(m_freeBlocks);
+ _deallocateBlocks(m_activeBlocks);
+ _deallocateBlocks(m_freeBlocks);
}
void FreeList::_init()
{
- m_top = nullptr;
- m_end = nullptr;
-
- m_activeBlocks = nullptr;
- m_freeBlocks = nullptr;
-
- m_freeElements = nullptr;
-
- m_elementSize = 0;
- m_alignment = 1;
- m_blockSize = 0;
- m_blockAllocationSize = 0;
+ m_top = nullptr;
+ m_end = nullptr;
+
+ m_activeBlocks = nullptr;
+ m_freeBlocks = nullptr;
+
+ m_freeElements = nullptr;
+
+ m_elementSize = 0;
+ m_alignment = 1;
+ m_blockSize = 0;
+ m_blockAllocationSize = 0;
}
void FreeList::_init(size_t elementSize, size_t alignment, size_t elemsPerBlock)
{
- alignment = (alignment < sizeof(void*)) ? sizeof(void*) : alignment;
+ alignment = (alignment < sizeof(void*)) ? sizeof(void*) : alignment;
- // Alignment must be a power of 2
- assert(((alignment - 1) & alignment) == 0);
+ // Alignment must be a power of 2
+ assert(((alignment - 1) & alignment) == 0);
- // The elementSize must at least be at least the same size as the alignment
- elementSize = (elementSize >= alignment) ? elementSize : alignment;
- m_blockSize = elementSize * elemsPerBlock;
- m_elementSize = elementSize;
- m_alignment = alignment;
+ // The elementSize must at least be at least the same size as the alignment
+ elementSize = (elementSize >= alignment) ? elementSize : alignment;
+ m_blockSize = elementSize * elemsPerBlock;
+ m_elementSize = elementSize;
+ m_alignment = alignment;
- // Calculate the block size need, correcting for alignment
- const size_t alignedBlockSize = (alignment <= DEFAULT_ALIGNMENT) ?
- _calcAlignedBlockSize(DEFAULT_ALIGNMENT) :
- _calcAlignedBlockSize(alignment);
+ // Calculate the block size need, correcting for alignment
+ const size_t alignedBlockSize = (alignment <= DEFAULT_ALIGNMENT)
+ ? _calcAlignedBlockSize(DEFAULT_ALIGNMENT)
+ : _calcAlignedBlockSize(alignment);
- // Make the block struct size aligned
- m_blockAllocationSize = m_blockSize + alignedBlockSize;
+ // Make the block struct size aligned
+ m_blockAllocationSize = m_blockSize + alignedBlockSize;
- m_top = nullptr;
- m_end = nullptr;
+ m_top = nullptr;
+ m_end = nullptr;
- m_activeBlocks = nullptr;
- m_freeBlocks = nullptr; ///< Blocks that there are no allocations in
+ m_activeBlocks = nullptr;
+ m_freeBlocks = nullptr; ///< Blocks that there are no allocations in
- m_freeElements = nullptr;
+ m_freeElements = nullptr;
}
void FreeList::init(size_t elementSize, size_t alignment, size_t elemsPerBlock)
{
- _deallocateBlocks(m_activeBlocks);
- _deallocateBlocks(m_freeBlocks);
- _init(elementSize, alignment, elemsPerBlock);
+ _deallocateBlocks(m_activeBlocks);
+ _deallocateBlocks(m_freeBlocks);
+ _init(elementSize, alignment, elemsPerBlock);
}
void FreeList::swapWith(ThisType& rhs)
{
- Swap(m_top, rhs.m_top);
- Swap(m_end, rhs.m_end);
-
- Swap(m_activeBlocks, rhs.m_activeBlocks);
- Swap(m_freeBlocks, rhs.m_freeBlocks);
-
- Swap(m_freeElements, rhs.m_freeElements);
-
- Swap(m_elementSize, rhs.m_elementSize);
- Swap(m_alignment, rhs.m_alignment);
- Swap(m_blockSize, rhs.m_blockSize);
- Swap(m_blockAllocationSize, rhs.m_blockAllocationSize);
+ Swap(m_top, rhs.m_top);
+ Swap(m_end, rhs.m_end);
+
+ Swap(m_activeBlocks, rhs.m_activeBlocks);
+ Swap(m_freeBlocks, rhs.m_freeBlocks);
+
+ Swap(m_freeElements, rhs.m_freeElements);
+
+ Swap(m_elementSize, rhs.m_elementSize);
+ Swap(m_alignment, rhs.m_alignment);
+ Swap(m_blockSize, rhs.m_blockSize);
+ Swap(m_blockAllocationSize, rhs.m_blockAllocationSize);
}
void FreeList::_deallocateBlocks(Block* block)
{
- while (block)
- {
- Block* next = block->m_next;
+ while (block)
+ {
+ Block* next = block->m_next;
#ifdef SLANG_FREE_LIST_INIT_MEM
- Memory::set(block, 0xfd, m_blockAllocationSize);
+ Memory::set(block, 0xfd, m_blockAllocationSize);
#endif
- ::free(block); // deallocate(block, m_blockAllocationSize);
- block = next;
- }
+ ::free(block); // deallocate(block, m_blockAllocationSize);
+ block = next;
+ }
}
bool FreeList::isValidAllocation(const void* dataIn) const
{
- uint8_t* data = (uint8_t*)dataIn;
-
- Block* block = m_activeBlocks;
- while (block)
- {
- uint8_t* start = block->m_data;
- uint8_t* end = start + m_blockSize;
-
- if (data >= start && data < end)
- {
- // Check it's aligned correctly
- if ((data - start) % m_elementSize)
- {
- return false;
- }
-
- // Non allocated data is between top and end
- if (data >= m_top && data < m_end)
- {
- return false;
- }
-
- // It can't be in the free list
- Element* ele = m_freeElements;
- while (ele)
- {
- if (ele == (Element*)data)
- {
- return false;
- }
-
- ele = ele->m_next;
- }
- return true;
- }
-
- block = block->m_next;
- }
- // It's not in an active block -> it cannot be a valid allocation
- return false;
+ uint8_t* data = (uint8_t*)dataIn;
+
+ Block* block = m_activeBlocks;
+ while (block)
+ {
+ uint8_t* start = block->m_data;
+ uint8_t* end = start + m_blockSize;
+
+ if (data >= start && data < end)
+ {
+ // Check it's aligned correctly
+ if ((data - start) % m_elementSize)
+ {
+ return false;
+ }
+
+ // Non allocated data is between top and end
+ if (data >= m_top && data < m_end)
+ {
+ return false;
+ }
+
+ // It can't be in the free list
+ Element* ele = m_freeElements;
+ while (ele)
+ {
+ if (ele == (Element*)data)
+ {
+ return false;
+ }
+
+ ele = ele->m_next;
+ }
+ return true;
+ }
+
+ block = block->m_next;
+ }
+ // It's not in an active block -> it cannot be a valid allocation
+ return false;
}
void* FreeList::_allocate()
{
- Block* block = m_freeBlocks;
- if (block)
- {
- /// Remove from the free blocks
- m_freeBlocks = block->m_next;
- }
- else
- {
- //block = (Block*)m_allocator->allocate(m_blockAllocationSize);
- block = (Block*)::malloc(m_blockAllocationSize);
- if (!block)
- {
- // Allocation failed... doh
- return nullptr;
- }
- // Do the alignment
- {
- size_t fix = (size_t(block) + sizeof(Block) + m_alignment - 1) & ~(m_alignment - 1);
- block->m_data = (uint8_t*)fix;
- }
- }
-
- // Attach to the active blocks
- block->m_next = m_activeBlocks;
- m_activeBlocks = block;
-
- // Set up top and end
- m_end = block->m_data + m_blockSize;
-
- // Return the first element
- uint8_t* element = block->m_data;
- m_top = element + m_elementSize;
-
- SLANG_FREE_LIST_INIT_ALLOCATE(element)
-
- return element;
+ Block* block = m_freeBlocks;
+ if (block)
+ {
+ /// Remove from the free blocks
+ m_freeBlocks = block->m_next;
+ }
+ else
+ {
+ // block = (Block*)m_allocator->allocate(m_blockAllocationSize);
+ block = (Block*)::malloc(m_blockAllocationSize);
+ if (!block)
+ {
+ // Allocation failed... doh
+ return nullptr;
+ }
+ // Do the alignment
+ {
+ size_t fix = (size_t(block) + sizeof(Block) + m_alignment - 1) & ~(m_alignment - 1);
+ block->m_data = (uint8_t*)fix;
+ }
+ }
+
+ // Attach to the active blocks
+ block->m_next = m_activeBlocks;
+ m_activeBlocks = block;
+
+ // Set up top and end
+ m_end = block->m_data + m_blockSize;
+
+ // Return the first element
+ uint8_t* element = block->m_data;
+ m_top = element + m_elementSize;
+
+ SLANG_FREE_LIST_INIT_ALLOCATE(element)
+
+ return element;
}
void FreeList::deallocateAll()
{
- Block* block = m_activeBlocks;
- if (block)
- {
- // Find the end block
- while (block->m_next)
- {
+ Block* block = m_activeBlocks;
+ if (block)
+ {
+ // Find the end block
+ while (block->m_next)
+ {
#ifdef SLANG_FREE_LIST_INIT_MEM
- Memory::set(block->m_data, 0xfd, m_blockSize);
+ Memory::set(block->m_data, 0xfd, m_blockSize);
#endif
- block = block->m_next;
- }
- // Attach to the freeblocks
- block->m_next = m_freeBlocks;
- // The list is now all freelists
- m_freeBlocks = m_activeBlocks;
- // There are no active blocks
- m_activeBlocks = nullptr;
- }
-
- m_top = nullptr;
- m_end = nullptr;
+ block = block->m_next;
+ }
+ // Attach to the freeblocks
+ block->m_next = m_freeBlocks;
+ // The list is now all freelists
+ m_freeBlocks = m_activeBlocks;
+ // There are no active blocks
+ m_activeBlocks = nullptr;
+ }
+
+ m_top = nullptr;
+ m_end = nullptr;
}
void FreeList::reset()
{
- _deallocateBlocks(m_activeBlocks);
- _deallocateBlocks(m_freeBlocks);
+ _deallocateBlocks(m_activeBlocks);
+ _deallocateBlocks(m_freeBlocks);
- m_top = nullptr;
- m_end = nullptr;
+ m_top = nullptr;
+ m_end = nullptr;
- m_activeBlocks = nullptr;
- m_freeBlocks = nullptr;
+ m_activeBlocks = nullptr;
+ m_freeBlocks = nullptr;
- m_freeElements = nullptr;
+ m_freeElements = nullptr;
}
void FreeList::_initAllocate(void* mem)
{
- ::memset(mem, 0xcd, m_elementSize);
+ ::memset(mem, 0xcd, m_elementSize);
}
void FreeList::_initDeallocate(void* mem)
{
- ::memset(mem, 0xfd, m_elementSize);
+ ::memset(mem, 0xfd, m_elementSize);
}
} // namespace Slang
-
diff --git a/source/core/slang-free-list.h b/source/core/slang-free-list.h
index 5c4e55607..74b3d63ea 100644
--- a/source/core/slang-free-list.h
+++ b/source/core/slang-free-list.h
@@ -1,145 +1,157 @@
#ifndef SLANG_CORE_FREE_LIST_H
#define SLANG_CORE_FREE_LIST_H
-#include "slang.h"
-
#include "slang-common.h"
+#include "slang.h"
#include <stdlib.h>
#include <string.h>
-namespace Slang {
+namespace Slang
+{
#if SLANG_DEBUG
-# define SLANG_FREE_LIST_INIT_MEM
+#define SLANG_FREE_LIST_INIT_MEM
#endif
#ifdef SLANG_FREE_LIST_INIT_MEM
-# define SLANG_FREE_LIST_INIT_ALLOCATE(ptr) _initAllocate(ptr);
-# define SLANG_FREE_LIST_INIT_DEALLOCATE(ptr) _initDeallocate(ptr);
+#define SLANG_FREE_LIST_INIT_ALLOCATE(ptr) _initAllocate(ptr);
+#define SLANG_FREE_LIST_INIT_DEALLOCATE(ptr) _initDeallocate(ptr);
#else
-# define SLANG_FREE_LIST_INIT_ALLOCATE(ptr)
-# define SLANG_FREE_LIST_INIT_DEALLOCATE(ptr)
+#define SLANG_FREE_LIST_INIT_ALLOCATE(ptr)
+#define SLANG_FREE_LIST_INIT_DEALLOCATE(ptr)
#endif
-/*! \brief A freelist is a simple and fast memory allocator that can allocate and free in any order identically sized blocks.
+/*! \brief A freelist is a simple and fast memory allocator that can allocate and free in any order
+identically sized blocks.
-\details A free list is a memory allocation system that performs allocations/deallocations very quickly for elements which are
-all the same size.
-In a freelist all elements are the same size, and elements can be allocated and freed in any order, as long as every deallocation
-matches every allocation. Both allocation and deallocation are O(1), and generally just a few instructions. The underlying
-memory allocator will allocate in large blocks, with multiple elements amortizing a more costly large allocation against lots
-of fast small element allocations. */
+\details A free list is a memory allocation system that performs allocations/deallocations very
+quickly for elements which are all the same size. In a freelist all elements are the same size, and
+elements can be allocated and freed in any order, as long as every deallocation matches every
+allocation. Both allocation and deallocation are O(1), and generally just a few instructions. The
+underlying memory allocator will allocate in large blocks, with multiple elements amortizing a more
+costly large allocation against lots of fast small element allocations. */
class FreeList
{
- public:
- typedef FreeList ThisType;
-
- enum { DEFAULT_ALIGNMENT = sizeof(void*) };
-
- /// Free elements are held in a singly linked list. The minimum size of an element is therefore a pointer
- struct Element
- {
- Element* m_next;
- };
- struct Block
- {
- Block* m_next; ///< The next block
- uint8_t* m_data; ///< The list of the elements each m_elementSize in size
- };
-
- /// Allocate a single element
- SLANG_FORCE_INLINE void* allocate();
- /// Deallocate a block that was previously allocated with allocate
- SLANG_FORCE_INLINE void deallocate(void* data);
-
- /// Returns true if this is from a valid allocation
- bool isValidAllocation(const void* dataIn) const;
-
- /// Get the element size
- SLANG_FORCE_INLINE size_t getElementSize() const { return m_elementSize; }
- /// Get the total size of each individual block allocation in bytes
- SLANG_FORCE_INLINE size_t getBlockSize() const { return m_blockSize; }
-
- /// Deallocates all elements
- void deallocateAll();
- /// Deallocates all, and frees any backing memory (put in initial state)
- void reset();
-
- /// Initialize. If called on an already initialized heap, the heap will be deallocated.
- void init(size_t elementSize, size_t alignment, size_t elemsPerBlock);
-
- /// Swap this with rhs
- void swapWith(ThisType& rhs);
-
- /// Default Ctor
- FreeList() { _init(); }
- /// Ctor
- FreeList(size_t elementSize, size_t alignment, size_t elemsPerBlock) { _init(elementSize, alignment, elemsPerBlock); }
- /// Dtor
- ~FreeList();
-
- protected:
- /// Initializes assuming freelist is not constructed
- void _init(size_t elementSize, size_t alignment, size_t elemsPerBlock);
- void* _allocate();
- void _deallocateBlocks(Block* block);
- /// Initializes setting everything to empty (doesn't free anything if already allocated)
- void _init();
-
- SLANG_FORCE_INLINE static size_t _calcAlignedBlockSize(size_t align) { return (sizeof(Block) + align - 1) & ~(align - 1); }
-
- void _initAllocate(void* mem);
- void _initDeallocate(void* mem);
-
- uint8_t* m_top; ///< The top position of the current block
- uint8_t* m_end; ///< The end of the current block
-
- Block* m_activeBlocks; ///< The blocks there are potentially allocations from
- Block* m_freeBlocks; ///< Blocks that there are no allocations in
-
- Element* m_freeElements; ///< A singly linked list of elements available
-
- size_t m_elementSize;
- size_t m_alignment;
- size_t m_blockSize;
- size_t m_blockAllocationSize; ///< The actual allocation size. Maybe bigger than m_blockSize if alignment requires it.
+public:
+ typedef FreeList ThisType;
+
+ enum
+ {
+ DEFAULT_ALIGNMENT = sizeof(void*)
+ };
+
+ /// Free elements are held in a singly linked list. The minimum size of an element is therefore
+ /// a pointer
+ struct Element
+ {
+ Element* m_next;
+ };
+ struct Block
+ {
+ Block* m_next; ///< The next block
+ uint8_t* m_data; ///< The list of the elements each m_elementSize in size
+ };
+
+ /// Allocate a single element
+ SLANG_FORCE_INLINE void* allocate();
+ /// Deallocate a block that was previously allocated with allocate
+ SLANG_FORCE_INLINE void deallocate(void* data);
+
+ /// Returns true if this is from a valid allocation
+ bool isValidAllocation(const void* dataIn) const;
+
+ /// Get the element size
+ SLANG_FORCE_INLINE size_t getElementSize() const { return m_elementSize; }
+ /// Get the total size of each individual block allocation in bytes
+ SLANG_FORCE_INLINE size_t getBlockSize() const { return m_blockSize; }
+
+ /// Deallocates all elements
+ void deallocateAll();
+ /// Deallocates all, and frees any backing memory (put in initial state)
+ void reset();
+
+ /// Initialize. If called on an already initialized heap, the heap will be deallocated.
+ void init(size_t elementSize, size_t alignment, size_t elemsPerBlock);
+
+ /// Swap this with rhs
+ void swapWith(ThisType& rhs);
+
+ /// Default Ctor
+ FreeList() { _init(); }
+ /// Ctor
+ FreeList(size_t elementSize, size_t alignment, size_t elemsPerBlock)
+ {
+ _init(elementSize, alignment, elemsPerBlock);
+ }
+ /// Dtor
+ ~FreeList();
+
+protected:
+ /// Initializes assuming freelist is not constructed
+ void _init(size_t elementSize, size_t alignment, size_t elemsPerBlock);
+ void* _allocate();
+ void _deallocateBlocks(Block* block);
+ /// Initializes setting everything to empty (doesn't free anything if already allocated)
+ void _init();
+
+ SLANG_FORCE_INLINE static size_t _calcAlignedBlockSize(size_t align)
+ {
+ return (sizeof(Block) + align - 1) & ~(align - 1);
+ }
+
+ void _initAllocate(void* mem);
+ void _initDeallocate(void* mem);
+
+ uint8_t* m_top; ///< The top position of the current block
+ uint8_t* m_end; ///< The end of the current block
+
+ Block* m_activeBlocks; ///< The blocks there are potentially allocations from
+ Block* m_freeBlocks; ///< Blocks that there are no allocations in
+
+ Element* m_freeElements; ///< A singly linked list of elements available
+
+ size_t m_elementSize;
+ size_t m_alignment;
+ size_t m_blockSize;
+ size_t m_blockAllocationSize; ///< The actual allocation size. Maybe bigger than m_blockSize if
+ ///< alignment requires it.
};
// --------------------------------------------------------------------------
SLANG_FORCE_INLINE void* FreeList::allocate()
{
- // First see if there are any freeElements ready to go
- {
- Element* element = m_freeElements;
- if (element)
- {
- m_freeElements = element->m_next;
- SLANG_FREE_LIST_INIT_ALLOCATE(element)
- return element;
- }
- }
- if (m_top >= m_end)
- {
- return _allocate();
- }
- void* data = (void*)m_top;
- SLANG_FREE_LIST_INIT_ALLOCATE(data)
-
- m_top += m_elementSize;
- return data;
+ // First see if there are any freeElements ready to go
+ {
+ Element* element = m_freeElements;
+ if (element)
+ {
+ m_freeElements = element->m_next;
+ SLANG_FREE_LIST_INIT_ALLOCATE(element)
+ return element;
+ }
+ }
+ if (m_top >= m_end)
+ {
+ return _allocate();
+ }
+ void* data = (void*)m_top;
+ SLANG_FREE_LIST_INIT_ALLOCATE(data)
+
+ m_top += m_elementSize;
+ return data;
}
// --------------------------------------------------------------------------
SLANG_FORCE_INLINE void FreeList::deallocate(void* data)
{
- assert(isValidAllocation(data));
+ assert(isValidAllocation(data));
- SLANG_FREE_LIST_INIT_DEALLOCATE(data)
+ SLANG_FREE_LIST_INIT_DEALLOCATE(data)
- // Put onto the singly linked free element list
- Element* ele = (Element*)data;
- ele->m_next = m_freeElements;
- m_freeElements = ele;
+ // Put onto the singly linked free element list
+ Element* ele = (Element*)data;
+ ele->m_next = m_freeElements;
+ m_freeElements = ele;
}
} // namespace Slang
diff --git a/source/core/slang-func-ptr.h b/source/core/slang-func-ptr.h
index c861bc6b8..271b51ae1 100644
--- a/source/core/slang-func-ptr.h
+++ b/source/core/slang-func-ptr.h
@@ -6,7 +6,8 @@
namespace Slang
{
-template <typename TResult, typename... Arguments> class FuncPtr : public RefObject
+template<typename TResult, typename... Arguments>
+class FuncPtr : public RefObject
{
public:
virtual TResult operator()(Arguments...) const = 0;
@@ -15,7 +16,7 @@ public:
virtual ~FuncPtr() {}
};
-template <typename TResult, typename... Arguments>
+template<typename TResult, typename... Arguments>
class CdeclFuncPtr : public FuncPtr<TResult, Arguments...>
{
public:
@@ -27,7 +28,8 @@ private:
public:
CdeclFuncPtr(FuncType func)
: funcPtr(func)
- {}
+ {
+ }
virtual FuncPtr<TResult, Arguments...>* clone() override
{
auto rs = new CdeclFuncPtr<TResult, Arguments...>(funcPtr);
@@ -46,7 +48,7 @@ public:
}
};
-template <typename Class, typename TResult, typename... Arguments>
+template<typename Class, typename TResult, typename... Arguments>
class MemberFuncPtr : public FuncPtr<TResult, Arguments...>
{
public:
@@ -58,9 +60,9 @@ private:
public:
MemberFuncPtr(Class* obj, FuncType func)
- : funcPtr(func)
- , object(obj)
- {}
+ : funcPtr(func), object(obj)
+ {
+ }
virtual FuncPtr<TResult, Arguments...>* clone() override
{
auto rs = new MemberFuncPtr<Class, TResult, Arguments...>(object, funcPtr);
@@ -81,7 +83,7 @@ public:
}
};
-template <typename F, typename TResult, typename... Arguments>
+template<typename F, typename TResult, typename... Arguments>
class LambdaFuncPtr : public FuncPtr<TResult, Arguments...>
{
private:
@@ -90,7 +92,8 @@ private:
public:
LambdaFuncPtr(const F& _func)
: func(_func)
- {}
+ {
+ }
virtual TResult operator()(Arguments... params) const override { return func(params...); }
virtual FuncPtr<TResult, Arguments...>* clone() override
{
@@ -103,7 +106,8 @@ public:
}
};
-template <typename TResult, typename... Arguments> class Func
+template<typename TResult, typename... Arguments>
+class Func
{
private:
RefPtr<FuncPtr<TResult, Arguments...>> funcPtr;
@@ -114,12 +118,13 @@ public:
{
funcPtr = new CdeclFuncPtr<TResult, Arguments...>(func);
}
- template <typename Class>
+ template<typename Class>
Func(Class* object, typename MemberFuncPtr<Class, TResult, Arguments...>::FuncType func)
{
funcPtr = new MemberFuncPtr<Class, TResult, Arguments...>(object, func);
}
- template <typename TFuncObj> Func(const TFuncObj& func)
+ template<typename TFuncObj>
+ Func(const TFuncObj& func)
{
funcPtr = new LambdaFuncPtr<TFuncObj, TResult, Arguments...>(func);
}
@@ -128,13 +133,14 @@ public:
funcPtr = new CdeclFuncPtr<TResult, Arguments...>(func);
return *this;
}
- template <typename Class>
+ template<typename Class>
Func& operator=(const MemberFuncPtr<Class, TResult, Arguments...>& func)
{
funcPtr = new MemberFuncPtr<Class, TResult, Arguments...>(func);
return *this;
}
- template <typename TFuncObj> Func& operator=(const TFuncObj& func)
+ template<typename TFuncObj>
+ Func& operator=(const TFuncObj& func)
{
funcPtr = new LambdaFuncPtr<TFuncObj, TResult, Arguments...>(func);
return *this;
@@ -147,7 +153,8 @@ public:
// template<typename... Arguments>
// using Action = Func<void, Arguments...>;
-template <typename... Arguments> class Action : public Func<void, Arguments...>
+template<typename... Arguments>
+class Action : public Func<void, Arguments...>
{
private:
RefPtr<FuncPtr<void, Arguments...>> funcPtr;
@@ -159,12 +166,13 @@ public:
{
funcPtr = new CdeclFuncPtr<void, Arguments...>(func);
}
- template <typename Class>
+ template<typename Class>
Action(Class* object, typename MemberFuncPtr<Class, void, Arguments...>::FuncType func)
{
funcPtr = new MemberFuncPtr<Class, void, Arguments...>(object, func);
}
- template <typename TFuncObj> Action(const TFuncObj& func)
+ template<typename TFuncObj>
+ Action(const TFuncObj& func)
{
funcPtr = new LambdaFuncPtr<TFuncObj, void, Arguments...>(func);
}
@@ -173,13 +181,14 @@ public:
funcPtr = new CdeclFuncPtr<void, Arguments...>(func);
return *this;
}
- template <typename Class>
+ template<typename Class>
Action& operator=(const MemberFuncPtr<Class, void, Arguments...>& func)
{
funcPtr = new MemberFuncPtr<Class, void, Arguments...>(func);
return *this;
}
- template <typename TFuncObj> Action& operator=(const TFuncObj& func)
+ template<typename TFuncObj>
+ Action& operator=(const TFuncObj& func)
{
funcPtr = new LambdaFuncPtr<TFuncObj, void, Arguments...>(func);
return *this;
diff --git a/source/core/slang-hash.h b/source/core/slang-hash.h
index 12239221b..ebe3d1973 100644
--- a/source/core/slang-hash.h
+++ b/source/core/slang-hash.h
@@ -1,225 +1,226 @@
#ifndef SLANG_CORE_HASH_H
#define SLANG_CORE_HASH_H
+#include "../../external/unordered_dense/include/ankerl/unordered_dense.h"
#include "slang-math.h"
#include "slang.h"
-#include "../../external/unordered_dense/include/ankerl/unordered_dense.h"
-
#include <cstring>
#include <type_traits>
namespace Slang
{
- //
- // Types
- //
-
- // A fixed 64bit wide hash on all targets.
- typedef uint64_t HashCode64;
- typedef HashCode64 HashCode;
- // A fixed 32bit wide hash on all targets.
- typedef uint32_t HashCode32;
-
- //
- // Some helpers to determine which hash to use for a type
- //
-
- // Forward declare Hash
- template<typename T> struct Hash;
-
- template<typename T, typename = void>
- constexpr static bool HasSlangHash = false;
- template<typename T>
- constexpr static bool HasSlangHash<
- T,
- std::enable_if_t<std::is_convertible_v<
- decltype((std::declval<const T&>()).getHashCode()),
- HashCode64>>>
- = true;
-
- // Does the hashmap implementation provide a uniform hash for this type.
- template<typename T, typename = void>
- constexpr static bool HasWyhash = false;
- template<typename T>
- constexpr static bool HasWyhash<T, typename ankerl::unordered_dense::hash<T>::is_avalanching> = true;
-
- // We want to have an associated type 'is_avalanching = void' iff we have a
- // hash with good uniformity, the two specializations here add that member
- // when appropriate (since we can't declare an associated type with
- // constexpr if or something terse like that)
- template <typename T, typename = void>
- struct DetectAvalanchingHash {};
- template <typename T>
- struct DetectAvalanchingHash<T, std::enable_if_t<HasWyhash<T>>>
- {
- using is_avalanching = void;
- };
- // Have we marked 'getHashCode' as having good uniformity properties.
- template <typename T>
- struct DetectAvalanchingHash<T, std::enable_if_t<T::kHasUniformHash>>
- {
- using is_avalanching = void;
- };
+//
+// Types
+//
+
+// A fixed 64bit wide hash on all targets.
+typedef uint64_t HashCode64;
+typedef HashCode64 HashCode;
+// A fixed 32bit wide hash on all targets.
+typedef uint32_t HashCode32;
+
+//
+// Some helpers to determine which hash to use for a type
+//
+
+// Forward declare Hash
+template<typename T>
+struct Hash;
+
+template<typename T, typename = void>
+constexpr static bool HasSlangHash = false;
+template<typename T>
+constexpr static bool HasSlangHash<
+ T,
+ std::enable_if_t<
+ std::is_convertible_v<decltype((std::declval<const T&>()).getHashCode()), HashCode64>>> =
+ true;
+
+// Does the hashmap implementation provide a uniform hash for this type.
+template<typename T, typename = void>
+constexpr static bool HasWyhash = false;
+template<typename T>
+constexpr static bool HasWyhash<T, typename ankerl::unordered_dense::hash<T>::is_avalanching> =
+ true;
+
+// We want to have an associated type 'is_avalanching = void' iff we have a
+// hash with good uniformity, the two specializations here add that member
+// when appropriate (since we can't declare an associated type with
+// constexpr if or something terse like that)
+template<typename T, typename = void>
+struct DetectAvalanchingHash
+{
+};
+template<typename T>
+struct DetectAvalanchingHash<T, std::enable_if_t<HasWyhash<T>>>
+{
+ using is_avalanching = void;
+};
+// Have we marked 'getHashCode' as having good uniformity properties.
+template<typename T>
+struct DetectAvalanchingHash<T, std::enable_if_t<T::kHasUniformHash>>
+{
+ using is_avalanching = void;
+};
- // A helper for hashing according to the bit representation
- template<typename T, typename U>
- struct BitCastHash : DetectAvalanchingHash<U>
+// A helper for hashing according to the bit representation
+template<typename T, typename U>
+struct BitCastHash : DetectAvalanchingHash<U>
+{
+ auto operator()(const T& t) const
{
- auto operator()(const T& t) const
- {
- // Doesn't discard or invent bits
- static_assert(sizeof(T) == sizeof(U));
- // Can we copy bytes to and fro
- static_assert(std::is_trivially_copyable_v<T>);
- static_assert(std::is_trivially_copyable_v<U>);
- // Because we construct a U to memcpy into
- static_assert(std::is_trivially_constructible_v<U>);
-
- U u;
- memcpy(&u, &t, sizeof(T));
- return Hash<U>{}(u);
- }
- };
+ // Doesn't discard or invent bits
+ static_assert(sizeof(T) == sizeof(U));
+ // Can we copy bytes to and fro
+ static_assert(std::is_trivially_copyable_v<T>);
+ static_assert(std::is_trivially_copyable_v<U>);
+ // Because we construct a U to memcpy into
+ static_assert(std::is_trivially_constructible_v<U>);
+
+ U u;
+ memcpy(&u, &t, sizeof(T));
+ return Hash<U>{}(u);
+ }
+};
- //
- // Our hashing functor which disptaches to the most appropriate hashing
- // function for the type
- //
+//
+// Our hashing functor which disptaches to the most appropriate hashing
+// function for the type
+//
- template<typename T>
- struct Hash : DetectAvalanchingHash<T>
+template<typename T>
+struct Hash : DetectAvalanchingHash<T>
+{
+ auto operator()(const T& t) const
{
- auto operator()(const T& t) const
+ // Our preference is for any hash we've defined ourselves
+ if constexpr (HasSlangHash<T>)
+ return t.getHashCode();
+ // Otherwise fall back to any good hash provided by the hashmap
+ // library
+ else if constexpr (HasWyhash<T>)
+ return ankerl::unordered_dense::hash<T>{}(t);
+ // Otherwise fail
+ else
{
- // Our preference is for any hash we've defined ourselves
- if constexpr (HasSlangHash<T>)
- return t.getHashCode();
- // Otherwise fall back to any good hash provided by the hashmap
- // library
- else if constexpr (HasWyhash<T>)
- return ankerl::unordered_dense::hash<T>{}(t);
- // Otherwise fail
- else
- {
- // !sizeof(T*) is a 'false' which is dependent on T (pending P2593R0)
- static_assert(!sizeof(T*), "No hash implementation found for this type");
- // This is to avoid the return type being deduced as 'void' and creating further errors.
- return HashCode64(0);
- }
+ // !sizeof(T*) is a 'false' which is dependent on T (pending P2593R0)
+ static_assert(!sizeof(T*), "No hash implementation found for this type");
+ // This is to avoid the return type being deduced as 'void' and creating further errors.
+ return HashCode64(0);
}
- };
-
- // Specializations for float and double which hash 0 and -0 to distinct values
- template<>
- struct Hash<float> : BitCastHash<float, uint32_t> {};
- template<>
- struct Hash<double> : BitCastHash<double, uint64_t> {};
-
- //
- // Utility functions for using hashes
- //
-
- // A wrapper for Hash<TKey>
- template<typename TKey>
- auto getHashCode(const TKey& key)
- {
- return Hash<TKey>{}(key);
- }
-
- inline HashCode64 getHashCode(const char* buffer, std::size_t len)
- {
- return ankerl::unordered_dense::detail::wyhash::hash(buffer, len);
- }
-
- template<typename T>
- HashCode64 hashObjectBytes(const T& t)
- {
- static_assert(std::has_unique_object_representations_v<T>,
- "This type must have a unique object representation to use hashObjectBytes");
- return getHashCode(reinterpret_cast<const char*>(&t), sizeof(t));
}
+};
- // Use in a struct to declare a uniform hash which doens't care about the
- // structure of the members.
-# define SLANG_BYTEWISE_HASHABLE \
- static constexpr bool kHasUniformHash = true; \
- ::Slang::HashCode64 getHashCode() const \
- { \
- return ::Slang::hashObjectBytes(*this); \
- }
+// Specializations for float and double which hash 0 and -0 to distinct values
+template<>
+struct Hash<float> : BitCastHash<float, uint32_t>
+{
+};
+template<>
+struct Hash<double> : BitCastHash<double, uint64_t>
+{
+};
-# define SLANG_COMPONENTWISE_HASHABLE_1 \
- auto getHashCode() const \
- { \
- const auto& [m1] = *this; \
- return Slang::getHashCode(m1); \
- }
+//
+// Utility functions for using hashes
+//
-# define SLANG_COMPONENTWISE_HASHABLE_2 \
- auto getHashCode() const \
- { \
- const auto& [m1, m2] = *this; \
- return combineHash(::Slang::getHashCode(m1), ::Slang::getHashCode(m2)); \
- }
+// A wrapper for Hash<TKey>
+template<typename TKey>
+auto getHashCode(const TKey& key)
+{
+ return Hash<TKey>{}(key);
+}
- inline HashCode64 combineHash(HashCode64 h)
- {
- return h;
+inline HashCode64 getHashCode(const char* buffer, std::size_t len)
+{
+ return ankerl::unordered_dense::detail::wyhash::hash(buffer, len);
+}
+
+template<typename T>
+HashCode64 hashObjectBytes(const T& t)
+{
+ static_assert(
+ std::has_unique_object_representations_v<T>,
+ "This type must have a unique object representation to use hashObjectBytes");
+ return getHashCode(reinterpret_cast<const char*>(&t), sizeof(t));
+}
+
+// Use in a struct to declare a uniform hash which doens't care about the
+// structure of the members.
+#define SLANG_BYTEWISE_HASHABLE \
+ static constexpr bool kHasUniformHash = true; \
+ ::Slang::HashCode64 getHashCode() const \
+ { \
+ return ::Slang::hashObjectBytes(*this); \
}
- inline HashCode32 combineHash(HashCode32 h)
- {
- return h;
+#define SLANG_COMPONENTWISE_HASHABLE_1 \
+ auto getHashCode() const \
+ { \
+ const auto& [m1] = *this; \
+ return Slang::getHashCode(m1); \
}
- // A left fold of a mixing operation
- template<typename H1, typename H2, typename... Hs>
- auto combineHash(H1 n, H2 m, Hs... args)
- {
- // TODO: restrict the types here more, currently we tend to throw
- // unhashed integers in here along with proper hashes of objects.
- static_assert(std::is_convertible_v<H1, HashCode64> || std::is_convertible_v<H1, HashCode32>);
- static_assert(std::is_convertible_v<H2, HashCode64> || std::is_convertible_v<H2, HashCode32>);
- return combineHash((n * 16777619) ^ m, args...);
+#define SLANG_COMPONENTWISE_HASHABLE_2 \
+ auto getHashCode() const \
+ { \
+ const auto& [m1, m2] = *this; \
+ return combineHash(::Slang::getHashCode(m1), ::Slang::getHashCode(m2)); \
}
- struct Hasher
- {
- public:
- Hasher() {}
+inline HashCode64 combineHash(HashCode64 h)
+{
+ return h;
+}
- /// Hash the given `value` and combine it into this hash state
- template<typename T>
- void hashValue(T const& value)
- {
- // TODO: Eventually, we should replace `getHashCode`
- // with a "hash into" operation that takes the value
- // and a `Hasher`.
+inline HashCode32 combineHash(HashCode32 h)
+{
+ return h;
+}
- m_hashCode = combineHash(m_hashCode, getHashCode(value));
- }
+// A left fold of a mixing operation
+template<typename H1, typename H2, typename... Hs>
+auto combineHash(H1 n, H2 m, Hs... args)
+{
+ // TODO: restrict the types here more, currently we tend to throw
+ // unhashed integers in here along with proper hashes of objects.
+ static_assert(std::is_convertible_v<H1, HashCode64> || std::is_convertible_v<H1, HashCode32>);
+ static_assert(std::is_convertible_v<H2, HashCode64> || std::is_convertible_v<H2, HashCode32>);
+ return combineHash((n * 16777619) ^ m, args...);
+}
- /// Combine the given `hash` code into the hash state.
- ///
- /// Note: users should prefer to use `hashValue` or `hashObject`
- /// when possible, as they may be able to ensure a higher-quality
- /// hash result (e.g., by using more bits to represent the state
- /// during hashing than are used for the final hash code).
- ///
- void addHash(HashCode hash)
- {
- m_hashCode = combineHash(m_hashCode, hash);
- }
+struct Hasher
+{
+public:
+ Hasher() {}
- HashCode getResult() const
- {
- return m_hashCode;
- }
+ /// Hash the given `value` and combine it into this hash state
+ template<typename T>
+ void hashValue(T const& value)
+ {
+ // TODO: Eventually, we should replace `getHashCode`
+ // with a "hash into" operation that takes the value
+ // and a `Hasher`.
- private:
- HashCode m_hashCode = 0;
- };
-}
+ m_hashCode = combineHash(m_hashCode, getHashCode(value));
+ }
+
+ /// Combine the given `hash` code into the hash state.
+ ///
+ /// Note: users should prefer to use `hashValue` or `hashObject`
+ /// when possible, as they may be able to ensure a higher-quality
+ /// hash result (e.g., by using more bits to represent the state
+ /// during hashing than are used for the final hash code).
+ ///
+ void addHash(HashCode hash) { m_hashCode = combineHash(m_hashCode, hash); }
+
+ HashCode getResult() const { return m_hashCode; }
+
+private:
+ HashCode m_hashCode = 0;
+};
+} // namespace Slang
#endif
diff --git a/source/core/slang-hex-dump-util.cpp b/source/core/slang-hex-dump-util.cpp
index 46fe825ac..b400fb15b 100644
--- a/source/core/slang-hex-dump-util.cpp
+++ b/source/core/slang-hex-dump-util.cpp
@@ -1,14 +1,12 @@
// slang-hex-dump-util.cpp
#include "slang-hex-dump-util.h"
-#include "slang-common.h"
-#include "slang-string-util.h"
-#include "slang-writer.h"
-
#include "slang-char-util.h"
-
#include "slang-com-helper.h"
+#include "slang-common.h"
#include "slang-hash.h"
+#include "slang-string-util.h"
+#include "slang-writer.h"
namespace Slang
{
@@ -17,19 +15,26 @@ static const UnownedStringSlice s_start = UnownedStringSlice::fromLiteral("--STA
static const UnownedStringSlice s_end = UnownedStringSlice::fromLiteral("--END--");
static const char s_hex[] = "0123456789abcdef";
-/* static */SlangResult HexDumpUtil::dumpWithMarkers(const List<uint8_t>& data, int maxBytesPerLine, ISlangWriter* writer)
+/* static */ SlangResult HexDumpUtil::dumpWithMarkers(
+ const List<uint8_t>& data,
+ int maxBytesPerLine,
+ ISlangWriter* writer)
{
return dumpWithMarkers(data.getBuffer(), data.getCount(), maxBytesPerLine, writer);
}
-/* static */SlangResult HexDumpUtil::dumpWithMarkers(const uint8_t* data, size_t dataCount, int maxBytesPerLine, ISlangWriter* writer)
+/* static */ SlangResult HexDumpUtil::dumpWithMarkers(
+ const uint8_t* data,
+ size_t dataCount,
+ int maxBytesPerLine,
+ ISlangWriter* writer)
{
WriterHelper helper(writer);
SLANG_RETURN_ON_FAIL(helper.write(s_start.begin(), s_start.getLength()));
SLANG_RETURN_ON_FAIL(helper.print(" %zu", dataCount));
const StableHashCode32 hash = getStableHashCode32((const char*)data, dataCount);
- SLANG_RETURN_ON_FAIL(helper.print(" %d\n", hash.hash ));
+ SLANG_RETURN_ON_FAIL(helper.print(" %d\n", hash.hash));
SLANG_RETURN_ON_FAIL(dump(data, dataCount, maxBytesPerLine, writer));
@@ -38,7 +43,7 @@ static const char s_hex[] = "0123456789abcdef";
return SLANG_OK;
}
-/* static */void HexDumpUtil::dump(uint32_t value, ISlangWriter* writer)
+/* static */ void HexDumpUtil::dump(uint32_t value, ISlangWriter* writer)
{
char c[9];
for (int i = 0; i < 8; ++i)
@@ -50,12 +55,19 @@ static const char s_hex[] = "0123456789abcdef";
}
-/* static */SlangResult HexDumpUtil::dump(const List<uint8_t>& data, int maxBytesPerLine, ISlangWriter* writer)
+/* static */ SlangResult HexDumpUtil::dump(
+ const List<uint8_t>& data,
+ int maxBytesPerLine,
+ ISlangWriter* writer)
{
return dump(data.getBuffer(), data.getCount(), maxBytesPerLine, writer);
}
-SlangResult HexDumpUtil::dumpSourceBytes(const uint8_t* data, size_t dataCount, int maxBytesPerLine, ISlangWriter* writer)
+SlangResult HexDumpUtil::dumpSourceBytes(
+ const uint8_t* data,
+ size_t dataCount,
+ int maxBytesPerLine,
+ ISlangWriter* writer)
{
const uint8_t* cur = data;
const uint8_t* end = data + dataCount;
@@ -95,13 +107,17 @@ SlangResult HexDumpUtil::dumpSourceBytes(const uint8_t* data, size_t dataCount,
return SLANG_OK;
}
-/* static */SlangResult HexDumpUtil::dump(const uint8_t* data, size_t dataCount, int maxBytesPerLine, ISlangWriter* writer)
+/* static */ SlangResult HexDumpUtil::dump(
+ const uint8_t* data,
+ size_t dataCount,
+ int maxBytesPerLine,
+ ISlangWriter* writer)
{
int maxCharsPerLine = 2 * maxBytesPerLine + 1 + maxBytesPerLine + 1;
const uint8_t* cur = data;
const uint8_t* end = data + dataCount;
-
+
while (cur < end)
{
size_t count = size_t(end - cur);
@@ -121,7 +137,7 @@ SlangResult HexDumpUtil::dumpSourceBytes(const uint8_t* data, size_t dataCount,
for (size_t i = count; i < size_t(maxBytesPerLine); ++i)
{
*dst++ = ' ';
- *dst++ = ' ';
+ *dst++ = ' ';
}
*dst++ = ' ';
@@ -130,9 +146,7 @@ SlangResult HexDumpUtil::dumpSourceBytes(const uint8_t* data, size_t dataCount,
{
char c = char(cur[i]);
- if ((c >= '0' && c <= '9') ||
- (c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
+ if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= 32 && (c & 0x80) == 0))
{
}
@@ -154,7 +168,9 @@ SlangResult HexDumpUtil::dumpSourceBytes(const uint8_t* data, size_t dataCount,
return SLANG_OK;
}
-/* static */SlangResult HexDumpUtil::parse(const UnownedStringSlice& lines, List<uint8_t>& outBytes)
+/* static */ SlangResult HexDumpUtil::parse(
+ const UnownedStringSlice& lines,
+ List<uint8_t>& outBytes)
{
outBytes.clear();
@@ -164,7 +180,7 @@ SlangResult HexDumpUtil::dumpSourceBytes(const uint8_t* data, size_t dataCount,
const char* cur = line.begin();
const char* end = line.end();
- while(cur + 2 <= end)
+ while (cur + 2 <= end)
{
const char c = cur[0];
if (c == ' ' || c == '\n' || c == '\r' || c == '\t')
@@ -188,7 +204,10 @@ SlangResult HexDumpUtil::dumpSourceBytes(const uint8_t* data, size_t dataCount,
return SLANG_OK;
}
-static SlangResult _findLine(const UnownedStringSlice& find, UnownedStringSlice& ioRemaining, UnownedStringSlice& outLine)
+static SlangResult _findLine(
+ const UnownedStringSlice& find,
+ UnownedStringSlice& ioRemaining,
+ UnownedStringSlice& outLine)
{
// Find the start line
UnownedStringSlice line;
@@ -203,7 +222,10 @@ static SlangResult _findLine(const UnownedStringSlice& find, UnownedStringSlice&
return SLANG_FAIL;
}
-/* static */SlangResult HexDumpUtil::findStartAndEndLines(const UnownedStringSlice& lines, UnownedStringSlice& outStart, UnownedStringSlice& outEnd)
+/* static */ SlangResult HexDumpUtil::findStartAndEndLines(
+ const UnownedStringSlice& lines,
+ UnownedStringSlice& outStart,
+ UnownedStringSlice& outEnd)
{
UnownedStringSlice remaining(lines);
SLANG_RETURN_ON_FAIL(_findLine(s_start, remaining, outStart));
@@ -211,7 +233,9 @@ static SlangResult _findLine(const UnownedStringSlice& find, UnownedStringSlice&
return SLANG_OK;
}
-/* static */SlangResult HexDumpUtil::parseWithMarkers(const UnownedStringSlice& lines, List<uint8_t>& outBytes)
+/* static */ SlangResult HexDumpUtil::parseWithMarkers(
+ const UnownedStringSlice& lines,
+ List<uint8_t>& outBytes)
{
UnownedStringSlice startLine, endLine;
SLANG_RETURN_ON_FAIL(findStartAndEndLines(lines, startLine, endLine));
@@ -234,7 +258,8 @@ static SlangResult _findLine(const UnownedStringSlice& find, UnownedStringSlice&
SLANG_RETURN_ON_FAIL(parse(UnownedStringSlice(startLine.end(), endLine.begin()), outBytes));
// Calc the hash
- const StableHashCode32 readHash = getStableHashCode32((const char*)outBytes.begin(), outBytes.getCount());
+ const StableHashCode32 readHash =
+ getStableHashCode32((const char*)outBytes.begin(), outBytes.getCount());
if (readHash != hash || size_t(outBytes.getCount()) != size)
{
@@ -243,4 +268,4 @@ static SlangResult _findLine(const UnownedStringSlice& find, UnownedStringSlice&
return SLANG_OK;
}
-}
+} // namespace Slang
diff --git a/source/core/slang-hex-dump-util.h b/source/core/slang-hex-dump-util.h
index 037355f2d..cfa2c4bb1 100644
--- a/source/core/slang-hex-dump-util.h
+++ b/source/core/slang-hex-dump-util.h
@@ -2,9 +2,8 @@
#define SLANG_HEX_DUMP_UTIL_H
#include "slang-common.h"
-#include "slang-string.h"
-
#include "slang-list.h"
+#include "slang-string.h"
#include "slang.h"
namespace Slang
@@ -12,30 +11,48 @@ namespace Slang
struct HexDumpUtil
{
- /// Dump out bytes in source format - as in
- /// 0x10, 0xab,
- static SlangResult dumpSourceBytes(const uint8_t* data, size_t dataCount, int maxBytesPerLine, ISlangWriter* writer);
-
- /// Dump data to writer, with lines starting with hex data
+ /// Dump out bytes in source format - as in
+ /// 0x10, 0xab,
+ static SlangResult dumpSourceBytes(
+ const uint8_t* data,
+ size_t dataCount,
+ int maxBytesPerLine,
+ ISlangWriter* writer);
+
+ /// Dump data to writer, with lines starting with hex data
static SlangResult dump(const List<uint8_t>& data, int numBytesPerLine, ISlangWriter* writer);
- static SlangResult dump(const uint8_t* data, size_t dataCount, int numBytesPerLine, ISlangWriter* writer);
+ static SlangResult dump(
+ const uint8_t* data,
+ size_t dataCount,
+ int numBytesPerLine,
+ ISlangWriter* writer);
- /// Dump a single value
+ /// Dump a single value
static void dump(uint32_t value, ISlangWriter* writer);
- static SlangResult dumpWithMarkers(const List<uint8_t>& data, int numBytesPerLine, ISlangWriter* writer);
+ static SlangResult dumpWithMarkers(
+ const List<uint8_t>& data,
+ int numBytesPerLine,
+ ISlangWriter* writer);
- static SlangResult dumpWithMarkers(const uint8_t* data, size_t dataSize, int numBytesPerLine, ISlangWriter* writer);
+ static SlangResult dumpWithMarkers(
+ const uint8_t* data,
+ size_t dataSize,
+ int numBytesPerLine,
+ ISlangWriter* writer);
- /// Parses lines formatted by dump, back into bytes
+ /// Parses lines formatted by dump, back into bytes
static SlangResult parse(const UnownedStringSlice& lines, List<uint8_t>& outBytes);
static SlangResult parseWithMarkers(const UnownedStringSlice& lines, List<uint8_t>& outBytes);
- static SlangResult findStartAndEndLines(const UnownedStringSlice& lines, UnownedStringSlice& outStart, UnownedStringSlice& outEnd);
+ static SlangResult findStartAndEndLines(
+ const UnownedStringSlice& lines,
+ UnownedStringSlice& outStart,
+ UnownedStringSlice& outEnd);
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-http.cpp b/source/core/slang-http.cpp
index 58f37666a..fa7ca952b 100644
--- a/source/core/slang-http.cpp
+++ b/source/core/slang-http.cpp
@@ -1,10 +1,10 @@
#include "slang-http.h"
-#include "slang-string-util.h"
-
#include "slang-process.h"
+#include "slang-string-util.h"
-namespace Slang {
+namespace Slang
+{
static const UnownedStringSlice g_headerEnd = UnownedStringSlice::fromLiteral("\r\n\r\n");
static const UnownedStringSlice g_contentLength = UnownedStringSlice::fromLiteral("Content-Length");
@@ -25,11 +25,11 @@ void HTTPHeader::reset()
m_arena.deallocateAll();
}
-/* static */SlangResult HTTPHeader::readHeaderText(BufferedReadStream* stream, Index& outEndIndex)
+/* static */ SlangResult HTTPHeader::readHeaderText(BufferedReadStream* stream, Index& outEndIndex)
{
// https://microsoft.github.io/language-server-protocol/specifications/specification-current/
- while(true)
+ while (true)
{
SLANG_RETURN_ON_FAIL(stream->update());
@@ -49,9 +49,10 @@ void HTTPHeader::reset()
}
}
-/* static */Index HTTPHeader::findHeaderEnd(BufferedReadStream* stream)
+/* static */ Index HTTPHeader::findHeaderEnd(BufferedReadStream* stream)
{
- // This could be more efficient - it just searches until there are enough bytes to have termination
+ // This could be more efficient - it just searches until there are enough bytes to have
+ // termination
auto bytes = stream->getView();
UnownedStringSlice input((const char*)bytes.begin(), (const char*)bytes.end());
@@ -59,7 +60,7 @@ void HTTPHeader::reset()
return (index >= 0) ? (index + g_headerEnd.getLength()) : index;
}
-/* static */SlangResult HTTPHeader::parse(const UnownedStringSlice& inSlice, HTTPHeader& out)
+/* static */ SlangResult HTTPHeader::parse(const UnownedStringSlice& inSlice, HTTPHeader& out)
{
out.reset();
@@ -70,8 +71,11 @@ void HTTPHeader::reset()
{
slice = slice.head(slice.getLength() - g_headerEnd.getLength());
}
- // Allocate on on the arena, so when we reference other slices, they are part of this allocation.
- out.m_header = UnownedStringSlice(out.m_arena.allocateString(slice.begin(), slice.getLength()), slice.getLength());
+ // Allocate on on the arena, so when we reference other slices, they are part of this
+ // allocation.
+ out.m_header = UnownedStringSlice(
+ out.m_arena.allocateString(slice.begin(), slice.getLength()),
+ slice.getLength());
}
// Okay, we need to split into lines, and then examine the contents
@@ -88,7 +92,7 @@ void HTTPHeader::reset()
const UnownedStringSlice value = line.tail(index + 1).trim();
// Add the pair
- Pair pair{ key, value };
+ Pair pair{key, value};
// We could check if key is already used. Some values can be repeated I believe.
// So we just allow for now.
@@ -138,7 +142,7 @@ void HTTPHeader::reset()
return SLANG_OK;
}
-/* static */SlangResult HTTPHeader::read(BufferedReadStream* stream, HTTPHeader& out)
+/* static */ SlangResult HTTPHeader::read(BufferedReadStream* stream, HTTPHeader& out)
{
Index endIndex;
SLANG_RETURN_ON_FAIL(readHeaderText(stream, endIndex));
@@ -167,8 +171,10 @@ void HTTPHeader::append(StringBuilder& out) const
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
- auto mimeType = m_mimeType.getLength() ? m_mimeType : UnownedStringSlice::fromLiteral("text/plain");
- auto encoding = m_encoding.getLength() ? m_encoding : UnownedStringSlice::fromLiteral("UTF-8");
+ auto mimeType =
+ m_mimeType.getLength() ? m_mimeType : UnownedStringSlice::fromLiteral("text/plain");
+ auto encoding =
+ m_encoding.getLength() ? m_encoding : UnownedStringSlice::fromLiteral("UTF-8");
out << mimeType << "; ";
out << "charset=" << encoding;
@@ -195,11 +201,11 @@ void HTTPHeader::append(StringBuilder& out) const
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! HTTPPacketConnection !!!!!!!!!!!!!!!!!!!!!!! */
-HTTPPacketConnection::HTTPPacketConnection(BufferedReadStream* readStream, Stream* writeStream) :
- m_readStream(readStream),
- m_writeStream(writeStream),
- m_readState(ReadState::Header),
- m_readResult(SLANG_OK)
+HTTPPacketConnection::HTTPPacketConnection(BufferedReadStream* readStream, Stream* writeStream)
+ : m_readStream(readStream)
+ , m_writeStream(writeStream)
+ , m_readState(ReadState::Header)
+ , m_readResult(SLANG_OK)
{
}
@@ -241,11 +247,11 @@ SlangResult HTTPPacketConnection::update()
{
switch (m_readState)
{
- case ReadState::Closed: return SLANG_OK;
- case ReadState::Error: return m_readResult;
- default: break;
+ case ReadState::Closed: return SLANG_OK;
+ case ReadState::Error: return m_readResult;
+ default: break;
}
-
+
SLANG_RETURN_ON_FAIL(_updateReadResult(m_readStream->update()));
// Note will only indicate end if the buffer *and* backing stream are end/empty
@@ -266,7 +272,7 @@ SlangResult HTTPPacketConnection::update()
switch (m_readState)
{
- case ReadState::Header:
+ case ReadState::Header:
{
SLANG_RETURN_ON_FAIL(_handleHeader());
// We might be able to progress through content, if we have the header
@@ -276,19 +282,20 @@ SlangResult HTTPPacketConnection::update()
}
break;
}
- case ReadState::Content:
+ case ReadState::Content:
{
_handleContent();
break;
}
- default: break;
+ default: break;
}
return m_readResult;
}
-namespace { // anonymous
+namespace
+{ // anonymous
// Handles binary backoff like sleeping mechanism.
struct SleepState
@@ -315,7 +322,8 @@ struct SleepState
// If we hit the count change the interval
if (m_count >= countThreshold)
{
- m_intervalInMs = (m_intervalInMs == 0) ? 1 : Math::Min(m_intervalInMs * 2, maxIntervalInMs);
+ m_intervalInMs =
+ (m_intervalInMs == 0) ? 1 : Math::Min(m_intervalInMs * 2, maxIntervalInMs);
// Reset the count
m_count = 0;
}
@@ -325,7 +333,7 @@ struct SleepState
Int m_count = 0;
};
-} // anonymous
+} // namespace
SlangResult HTTPPacketConnection::waitForResult(Int timeOutInMs)
{
@@ -342,8 +350,7 @@ SlangResult HTTPPacketConnection::waitForResult(Int timeOutInMs)
SleepState sleepState;
- while (m_readState == ReadState::Header ||
- m_readState == ReadState::Content)
+ while (m_readState == ReadState::Header || m_readState == ReadState::Content)
{
const auto prevCount = m_readStream->getCount();
diff --git a/source/core/slang-http.h b/source/core/slang-http.h
index 11d834bd8..44a0d4ccc 100644
--- a/source/core/slang-http.h
+++ b/source/core/slang-http.h
@@ -1,22 +1,19 @@
#ifndef SLANG_CORE_HTTP_H
#define SLANG_CORE_HTTP_H
-#include "slang.h"
-
-#include "slang-string.h"
+#include "slang-com-helper.h"
+#include "slang-com-ptr.h"
#include "slang-list.h"
-
#include "slang-memory-arena.h"
-
#include "slang-stream.h"
+#include "slang-string.h"
+#include "slang.h"
-#include "slang-com-helper.h"
-#include "slang-com-ptr.h"
-
-namespace Slang {
+namespace Slang
+{
-/// All of the contained UnownedStringSlice can be stored in m_header. This can be checked via testing if
-/// the memory overlaps.
+/// All of the contained UnownedStringSlice can be stored in m_header. This can be checked via
+/// testing if the memory overlaps.
///
/// The m_arena can be used to store slices in an ad-hoc manner to keep in scope with the Header.
struct HTTPHeader
@@ -27,45 +24,46 @@ struct HTTPHeader
UnownedStringSlice value;
};
- /// Append the header (including termination) to out
+ /// Append the header (including termination) to out
void append(StringBuilder& out) const;
- /// Reset the contents
+ /// Reset the contents
void reset();
SLANG_INLINE Index indexOfKey(const UnownedStringSlice& slice) const;
- /// Ctor
- HTTPHeader() :
- m_arena(1024)
+ /// Ctor
+ HTTPHeader()
+ : m_arena(1024)
{
}
- /// Reads from stream until the buffer contains all of the header. The outEndIndex will point
- /// past the header termination.
+ /// Reads from stream until the buffer contains all of the header. The outEndIndex will point
+ /// past the header termination.
static SlangResult readHeaderText(BufferedReadStream* stream, Index& outEndIndex);
- /// Returns the index of the end of the header (index of first byte *after* the header), or < if doesn't have an end
+ /// Returns the index of the end of the header (index of first byte *after* the header), or < if
+ /// doesn't have an end
static Index findHeaderEnd(BufferedReadStream* stream);
- /// Parse the slice (holding a header) into out.
- /// Will allocate the slice on the array and store in m_header.
- /// Slices will reference sections of m_header, that may be useful in some scenarios.
+ /// Parse the slice (holding a header) into out.
+ /// Will allocate the slice on the array and store in m_header.
+ /// Slices will reference sections of m_header, that may be useful in some scenarios.
static SlangResult parse(const UnownedStringSlice& slice, HTTPHeader& out);
- /// Read from buffered stream header, and place parsed header into out
+ /// Read from buffered stream header, and place parsed header into out
static SlangResult read(BufferedReadStream* stream, HTTPHeader& out);
- size_t m_contentLength; ///< Content length in bytes
+ size_t m_contentLength; ///< Content length in bytes
- UnownedStringSlice m_mimeType; ///< The mime type
- UnownedStringSlice m_encoding; ///< The character encoding
+ UnownedStringSlice m_mimeType; ///< The mime type
+ UnownedStringSlice m_encoding; ///< The character encoding
- UnownedStringSlice m_header; ///< Optionally holds the whole of the header
+ UnownedStringSlice m_header; ///< Optionally holds the whole of the header
- List<Pair> m_valuePairs; /// All of the value pairs
+ List<Pair> m_valuePairs; /// All of the value pairs
- MemoryArena m_arena; ///< Used to store backing memory
+ MemoryArena m_arena; ///< Used to store backing memory
private:
// Disable
@@ -76,15 +74,16 @@ private:
// -----------------------------------------------------------------
Index HTTPHeader::indexOfKey(const UnownedStringSlice& slice) const
{
- return m_valuePairs.findFirstIndex([&](const HTTPHeader::Pair& pair) -> bool { return pair.key == slice; });
+ return m_valuePairs.findFirstIndex(
+ [&](const HTTPHeader::Pair& pair) -> bool { return pair.key == slice; });
}
/// Implements a way to communicate over Streams via the HTTP *protocol*.
///
/// Allows for reading without blocking, via calls to 'update'. When a complete
/// HTTP 'packet' (combination of header and content) is available, the ReadState will
-/// become 'Done'. For this to work without blocking it relies on the stream backing the BufferedReadStream
-/// to be non blocking.
+/// become 'Done'. For this to work without blocking it relies on the stream backing the
+/// BufferedReadStream to be non blocking.
///
/// If it is only necessary to respond on complete packets 'waitForContent' can be used.
/// If this returns and ReadState is Done, then getHeader holds the current header, and getContent
@@ -93,50 +92,66 @@ Index HTTPHeader::indexOfKey(const UnownedStringSlice& slice) const
/// Once the packet has been processed 'consumeContent' can be used. Once consumeContent is called
/// both contents of getContent and getReadHeader will no longer be valid.
///
-/// Ie using the slice returned from getContent *after* consumeContent is called is *undefined behavior*.
-///
+/// Ie using the slice returned from getContent *after* consumeContent is called is *undefined
+/// behavior*.
+///
/// NOTE! that this does not implement HTTP over TCP/IP.
/// That said it could be used to communicate via the HTTP protocol over TCP/IP
/// if the Streams supplied were TCP/IP sockets.
class HTTPPacketConnection : public RefObject
{
public:
-
enum class ReadState
{
- Header, ///< Reading reader
- Content, ///< Reading content (ie header is read)
- Done, ///< The content is read
- Closed, ///< The read stream is closed - no further packets can be read
- Error, ///< In an error state - no further packets can be read
+ Header, ///< Reading reader
+ Content, ///< Reading content (ie header is read)
+ Done, ///< The content is read
+ Closed, ///< The read stream is closed - no further packets can be read
+ Error, ///< In an error state - no further packets can be read
};
- /// Update state
+ /// Update state
SlangResult update();
- /// Get the current read staet
+ /// Get the current read staet
ReadState getReadState() const { return m_readState; }
- /// Get the read header
- const HTTPHeader& getReadHeader() const { SLANG_ASSERT(hasHeader()); return m_readHeader; }
- /// Get the content
- ConstArrayView<Byte> getContent() const { SLANG_ASSERT(m_readState == ReadState::Done); return ConstArrayView<Byte>((const Byte*)m_readStream->getBuffer(), m_readHeader.m_contentLength); }
+ /// Get the read header
+ const HTTPHeader& getReadHeader() const
+ {
+ SLANG_ASSERT(hasHeader());
+ return m_readHeader;
+ }
+ /// Get the content
+ ConstArrayView<Byte> getContent() const
+ {
+ SLANG_ASSERT(m_readState == ReadState::Done);
+ return ConstArrayView<Byte>(
+ (const Byte*)m_readStream->getBuffer(),
+ m_readHeader.m_contentLength);
+ }
- /// Write. Will potentially block if write stream is blocking.
+ /// Write. Will potentially block if write stream is blocking.
SlangResult write(const void* content, size_t sizeInBytes);
- /// Blocks until some result - a packet, closure, or some kind of error or timeout.
- /// TimeOut of -1 means no timeout.
+ /// Blocks until some result - a packet, closure, or some kind of error or timeout.
+ /// TimeOut of -1 means no timeout.
SlangResult waitForResult(Int timeOutInMs = -1);
- /// Consume the content - so can read next content
+ /// Consume the content - so can read next content
void consumeContent();
- /// True if connection is active.
- bool isActive() const { return m_readState != ReadState::Error && m_readState != ReadState::Closed; }
+ /// True if connection is active.
+ bool isActive() const
+ {
+ return m_readState != ReadState::Error && m_readState != ReadState::Closed;
+ }
- bool hasHeader() const { return m_readState == ReadState::Content || m_readState == ReadState::Done; }
- /// True if has content (implies has header)
- bool hasContent() const { return m_readState == ReadState::Done; }
+ bool hasHeader() const
+ {
+ return m_readState == ReadState::Content || m_readState == ReadState::Done;
+ }
+ /// True if has content (implies has header)
+ bool hasContent() const { return m_readState == ReadState::Done; }
- /// Ctor
+ /// Ctor
HTTPPacketConnection(BufferedReadStream* readStream, Stream* writeStream);
protected:
diff --git a/source/core/slang-implicit-directory-collector.cpp b/source/core/slang-implicit-directory-collector.cpp
index d116ed8f9..a08597e6f 100644
--- a/source/core/slang-implicit-directory-collector.cpp
+++ b/source/core/slang-implicit-directory-collector.cpp
@@ -7,8 +7,10 @@ namespace Slang
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ImplicitDirectoryCollector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-ImplicitDirectoryCollector::ImplicitDirectoryCollector(const String& canonicalPath, bool directoryExists) :
- m_directoryExists(directoryExists)
+ImplicitDirectoryCollector::ImplicitDirectoryCollector(
+ const String& canonicalPath,
+ bool directoryExists)
+ : m_directoryExists(directoryExists)
{
if (!isRootPath(canonicalPath.getUnownedSlice()))
{
@@ -19,7 +21,7 @@ ImplicitDirectoryCollector::ImplicitDirectoryCollector(const String& canonicalPa
}
}
-/* static */bool ImplicitDirectoryCollector::isRootPath(const UnownedStringSlice& path)
+/* static */ bool ImplicitDirectoryCollector::isRootPath(const UnownedStringSlice& path)
{
const auto length = path.getLength();
if (length == 0)
@@ -34,7 +36,9 @@ ImplicitDirectoryCollector::ImplicitDirectoryCollector(const String& canonicalPa
return false;
}
-void ImplicitDirectoryCollector::addRemainingPath(SlangPathType pathType, const UnownedStringSlice& inPathRemainder)
+void ImplicitDirectoryCollector::addRemainingPath(
+ SlangPathType pathType,
+ const UnownedStringSlice& inPathRemainder)
{
// If it's zero length we probably don't want to add it
if (inPathRemainder.getLength() == 0)
@@ -51,7 +55,8 @@ void ImplicitDirectoryCollector::addRemainingPath(SlangPathType pathType, const
if (slashIndex >= 0)
{
pathType = SLANG_PATH_TYPE_DIRECTORY;
- pathRemainder = UnownedStringSlice(pathRemainder.begin(), pathRemainder.begin() + slashIndex);
+ pathRemainder =
+ UnownedStringSlice(pathRemainder.begin(), pathRemainder.begin() + slashIndex);
}
const Index countIndex = m_map.findOrAdd(pathRemainder, pathType);
@@ -60,7 +65,9 @@ void ImplicitDirectoryCollector::addRemainingPath(SlangPathType pathType, const
SLANG_ASSERT(SlangPathType(m_map.getValueAt(countIndex)) == pathType);
}
-void ImplicitDirectoryCollector::addPath(SlangPathType pathType, const UnownedStringSlice& canonicalPath)
+void ImplicitDirectoryCollector::addPath(
+ SlangPathType pathType,
+ const UnownedStringSlice& canonicalPath)
{
if (canonicalPath != toSlice(".") && hasPrefix(canonicalPath))
{
@@ -69,7 +76,9 @@ void ImplicitDirectoryCollector::addPath(SlangPathType pathType, const UnownedSt
}
}
-SlangResult ImplicitDirectoryCollector::enumerate(FileSystemContentsCallBack callback, void* userData)
+SlangResult ImplicitDirectoryCollector::enumerate(
+ FileSystemContentsCallBack callback,
+ void* userData)
{
const Int count = m_map.getCount();
diff --git a/source/core/slang-implicit-directory-collector.h b/source/core/slang-implicit-directory-collector.h
index 3b3505df2..72f3894dd 100644
--- a/source/core/slang-implicit-directory-collector.h
+++ b/source/core/slang-implicit-directory-collector.h
@@ -2,69 +2,77 @@
#define SLANG_CORE_IMPLICIT_DIRECTORY_COLLECTOR_H
#include "slang-basic.h"
-
#include "slang-string-slice-index-map.h"
namespace Slang
{
-/* This class helps to find the contents and/or existence of an implicit directory.This finds the contents of a directory.
+/* This class helps to find the contents and/or existence of an implicit directory.This finds the
+contents of a directory.
-This is achieved by using a path prefix that any contained path must at least match. If the remainder of the path contains a folder
- - detectable because it's not a leaf and so contains a delimiter - that directory is added. As a sub folder may contain many
- files, and the directory itself may also be defined, it is necessary to dedup. The deduping is handled by the StringSliceIndexMap. */
+This is achieved by using a path prefix that any contained path must at least match. If the
+remainder of the path contains a folder
+ - detectable because it's not a leaf and so contains a delimiter - that directory is added. As a
+sub folder may contain many files, and the directory itself may also be defined, it is necessary to
+dedup. The deduping is handled by the StringSliceIndexMap. */
class ImplicitDirectoryCollector
{
public:
-
enum class State
{
- None, ///< Neither the directory or content have been found
- DirectoryExists, ///< The directory exists
- HasContent, ///< If it has content, the directory must exist
+ None, ///< Neither the directory or content have been found
+ DirectoryExists, ///< The directory exists
+ HasContent, ///< If it has content, the directory must exist
};
- /// Get the current state
- State getState() const { return (m_map.getCount() > 0) ? State::HasContent : (m_directoryExists ? State::DirectoryExists : State::None); }
- /// True if collector at least has the specified state
+ /// Get the current state
+ State getState() const
+ {
+ return (m_map.getCount() > 0) ? State::HasContent
+ : (m_directoryExists ? State::DirectoryExists : State::None);
+ }
+ /// True if collector at least has the specified state
bool hasState(State state) { return Index(getState()) >= Index(state); }
- /// Set that it exists
+ /// Set that it exists
void setDirectoryExists(bool directoryExists) { m_directoryExists = directoryExists; }
- /// Get if it exists (implicitly or explicitly)
+ /// Get if it exists (implicitly or explicitly)
bool getDirectoryExists() const { return m_directoryExists || m_map.getCount() > 0; }
- /// True if the path matches the prefix
- bool hasPrefix(const UnownedStringSlice& path) const { return path.startsWith(m_prefix.getUnownedSlice()); }
+ /// True if the path matches the prefix
+ bool hasPrefix(const UnownedStringSlice& path) const
+ {
+ return path.startsWith(m_prefix.getUnownedSlice());
+ }
- /// True if the directory has content
+ /// True if the directory has content
bool hasContent() const { return m_map.getCount() > 0; }
- /// Gets the remainder or path after the prefix
+ /// Gets the remainder or path after the prefix
UnownedStringSlice getRemainder(const UnownedStringSlice& path) const
{
SLANG_ASSERT(hasPrefix(path));
return UnownedStringSlice(path.begin() + m_prefix.getLength(), path.end());
}
- /// Add a remaining path
+ /// Add a remaining path
void addRemainingPath(SlangPathType pathType, const UnownedStringSlice& inPathRemainder);
- /// Add a path
+ /// Add a path
void addPath(SlangPathType pathType, const UnownedStringSlice& canonicalPath);
- /// Enumerate the contents
+ /// Enumerate the contents
SlangResult enumerate(FileSystemContentsCallBack callback, void* userData);
- /// Ctor
+ /// Ctor
ImplicitDirectoryCollector(const String& canonicalPath, bool directoryExists = false);
static bool isRootPath(const UnownedStringSlice& path);
- protected:
+protected:
StringSliceIndexMap m_map;
String m_prefix;
bool m_directoryExists;
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index edd21639b..25c4c9389 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -1,15 +1,14 @@
#define _CRT_SECURE_NO_WARNINGS 1
#include "slang-io.h"
-#include "slang-exception.h"
+#include "slang-char-util.h"
#include "slang-com-helper.h"
-
+#include "slang-exception.h"
#include "slang-string-util.h"
-#include "slang-char-util.h"
#ifndef __STDC__
-# define __STDC__ 1
+#define __STDC__ 1
#endif
#include <sys/stat.h>
@@ -24,1366 +23,1392 @@
#endif
#if defined(__linux__) || defined(__CYGWIN__) || SLANG_APPLE_FAMILY || SLANG_WASM
-# include <fcntl.h>
-# include <unistd.h>
+#include <fcntl.h>
+#include <unistd.h>
// For Path::find
-# include <fnmatch.h>
-
-# include <dirent.h>
-# include <sys/stat.h>
-# include <sys/file.h>
-# include <ftw.h> // for nftw
+#include <dirent.h>
+#include <fnmatch.h>
+#include <ftw.h> // for nftw
+#include <sys/file.h>
+#include <sys/stat.h>
#endif
#if SLANG_APPLE_FAMILY
-# include <mach-o/dyld.h>
+#include <mach-o/dyld.h>
#endif
+#include <filesystem>
#include <limits.h> /* PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
-#include <filesystem>
namespace Slang
{
- /* static */SlangResult File::remove(const String& fileName)
- {
+/* static */ SlangResult File::remove(const String& fileName)
+{
#ifdef _WIN32
- // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-deletefilea
- if (DeleteFileA(fileName.getBuffer()))
- {
- return SLANG_OK;
- }
- return SLANG_FAIL;
+ // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-deletefilea
+ if (DeleteFileA(fileName.getBuffer()))
+ {
+ return SLANG_OK;
+ }
+ return SLANG_FAIL;
#else
- // https://linux.die.net/man/3/remove
- if (::remove(fileName.getBuffer()) == 0)
- {
- return SLANG_OK;
- }
- return SLANG_FAIL;
-#endif
+ // https://linux.die.net/man/3/remove
+ if (::remove(fileName.getBuffer()) == 0)
+ {
+ return SLANG_OK;
}
+ return SLANG_FAIL;
+#endif
+}
#ifdef _WIN32
- /* static */SlangResult File::generateTemporary(const UnownedStringSlice& inPrefix, Slang::String& outFileName)
- {
- // https://docs.microsoft.com/en-us/windows/win32/fileio/creating-and-using-a-temporary-file
-
- String tempPath;
- {
- int count = MAX_PATH + 1;
- while (true)
- {
- char* chars = tempPath.prepareForAppend(count);
- // Gets the temp path env string (no guarantee it's a valid path).
- // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
- DWORD ret = ::GetTempPathA(count - 1, chars);
- if (ret == 0)
- {
- return SLANG_FAIL;
- }
- if (ret > DWORD(count - 1))
- {
- count = ret + 1;
- continue;
- }
- tempPath.appendInPlace(chars, count);
- break;
- }
- }
-
- if (!File::exists(tempPath))
- {
- return SLANG_FAIL;
- }
-
- const String prefix(inPrefix);
- String tempFileName;
+/* static */ SlangResult File::generateTemporary(
+ const UnownedStringSlice& inPrefix,
+ Slang::String& outFileName)
+{
+ // https://docs.microsoft.com/en-us/windows/win32/fileio/creating-and-using-a-temporary-file
+ String tempPath;
+ {
+ int count = MAX_PATH + 1;
+ while (true)
{
- int count = MAX_PATH + 1;
- char* chars = tempFileName.prepareForAppend(count);
-
- // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea
- // Generates a temporary file name.
- // Will create a file with this name.
- DWORD ret = ::GetTempFileNameA(tempPath.getBuffer(), prefix.getBuffer(), 0, chars);
-
+ char* chars = tempPath.prepareForAppend(count);
+ // Gets the temp path env string (no guarantee it's a valid path).
+ // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
+ DWORD ret = ::GetTempPathA(count - 1, chars);
if (ret == 0)
{
return SLANG_FAIL;
}
- tempFileName.appendInPlace(chars, ::strlen(chars));
+ if (ret > DWORD(count - 1))
+ {
+ count = ret + 1;
+ continue;
+ }
+ tempPath.appendInPlace(chars, count);
+ break;
}
+ }
- SLANG_ASSERT(File::exists(tempFileName));
-
- outFileName = tempFileName;
- return SLANG_OK;
+ if (!File::exists(tempPath))
+ {
+ return SLANG_FAIL;
}
-#else
- /* static */SlangResult File::generateTemporary(const UnownedStringSlice& inPrefix, Slang::String& outFileName)
+
+ const String prefix(inPrefix);
+ String tempFileName;
+
{
- StringBuilder builder;
- builder << "/tmp/" << inPrefix << "-XXXXXX";
+ int count = MAX_PATH + 1;
+ char* chars = tempFileName.prepareForAppend(count);
- List<char> buffer;
- auto copySize = builder.getLength();
- buffer.setCount(copySize + 1);
- // Satisfy GCC
- SLANG_ASSUME(copySize < PTRDIFF_MAX && copySize > 0);
- ::memcpy(buffer.getBuffer(), builder.getBuffer(), copySize);
- buffer[copySize] = 0;
+ // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea
+ // Generates a temporary file name.
+ // Will create a file with this name.
+ DWORD ret = ::GetTempFileNameA(tempPath.getBuffer(), prefix.getBuffer(), 0, chars);
- int handle = mkstemp(buffer.getBuffer());
- if (handle == -1)
+ if (ret == 0)
{
return SLANG_FAIL;
}
+ tempFileName.appendInPlace(chars, ::strlen(chars));
+ }
- // Close the handle..
- close(handle);
-
- outFileName = buffer.getBuffer();
- SLANG_ASSERT(File::exists(outFileName));
+ SLANG_ASSERT(File::exists(tempFileName));
- return SLANG_OK;
+ outFileName = tempFileName;
+ return SLANG_OK;
+}
+#else
+/* static */ SlangResult File::generateTemporary(
+ const UnownedStringSlice& inPrefix,
+ Slang::String& outFileName)
+{
+ StringBuilder builder;
+ builder << "/tmp/" << inPrefix << "-XXXXXX";
+
+ List<char> buffer;
+ auto copySize = builder.getLength();
+ buffer.setCount(copySize + 1);
+ // Satisfy GCC
+ SLANG_ASSUME(copySize < PTRDIFF_MAX && copySize > 0);
+ ::memcpy(buffer.getBuffer(), builder.getBuffer(), copySize);
+ buffer[copySize] = 0;
+
+ int handle = mkstemp(buffer.getBuffer());
+ if (handle == -1)
+ {
+ return SLANG_FAIL;
}
+
+ // Close the handle..
+ close(handle);
+
+ outFileName = buffer.getBuffer();
+ SLANG_ASSERT(File::exists(outFileName));
+
+ return SLANG_OK;
+}
#endif
- /* static */SlangResult File::makeExecutable(const String& fileName)
- {
+/* static */ SlangResult File::makeExecutable(const String& fileName)
+{
#ifdef _WIN32
- SLANG_UNUSED(fileName);
- // As long as file extension is executable, it can be executed
- return SLANG_OK;
+ SLANG_UNUSED(fileName);
+ // As long as file extension is executable, it can be executed
+ return SLANG_OK;
#else
- struct stat st;
- if(::stat(fileName.getBuffer(), &st) != 0)
- {
- return SLANG_FAIL;
- }
- if(st.st_mode & S_IXUSR)
- {
- return SLANG_OK;
- }
- // It would probably be slightly neater to set all executable bits
- // aside from those in umask..
- if(::chmod(fileName.getBuffer(), st.st_mode & 07777 | S_IXUSR) != 0)
- {
- return SLANG_FAIL;
- }
+ struct stat st;
+ if (::stat(fileName.getBuffer(), &st) != 0)
+ {
+ return SLANG_FAIL;
+ }
+ if (st.st_mode & S_IXUSR)
+ {
return SLANG_OK;
-#endif
}
+ // It would probably be slightly neater to set all executable bits
+ // aside from those in umask..
+ if (::chmod(fileName.getBuffer(), st.st_mode & 07777 | S_IXUSR) != 0)
+ {
+ return SLANG_FAIL;
+ }
+ return SLANG_OK;
+#endif
+}
- bool File::exists(const String& fileName)
- {
+bool File::exists(const String& fileName)
+{
#ifdef _WIN32
- struct _stat32 statVar;
- return ::_wstat32(((String)fileName).toWString(), &statVar) != -1;
+ struct _stat32 statVar;
+ return ::_wstat32(((String)fileName).toWString(), &statVar) != -1;
#else
- struct stat statVar;
- return ::stat(fileName.getBuffer(), &statVar) == 0;
+ struct stat statVar;
+ return ::stat(fileName.getBuffer(), &statVar) == 0;
#endif
- }
-
- String Path::replaceExt(const String& path, const char* newExt)
- {
- StringBuilder sb(path.getLength() + 10);
- Index dotPos = findExtIndex(path);
+}
- if (dotPos < 0)
- dotPos = path.getLength();
- sb.append(path.getBuffer(), dotPos);
- sb.append('.');
- sb.append(newExt);
- return sb.produceString();
- }
+String Path::replaceExt(const String& path, const char* newExt)
+{
+ StringBuilder sb(path.getLength() + 10);
+ Index dotPos = findExtIndex(path);
+
+ if (dotPos < 0)
+ dotPos = path.getLength();
+ sb.append(path.getBuffer(), dotPos);
+ sb.append('.');
+ sb.append(newExt);
+ return sb.produceString();
+}
- /* static */ Index Path::findLastSeparatorIndex(UnownedStringSlice const& path)
+/* static */ Index Path::findLastSeparatorIndex(UnownedStringSlice const& path)
+{
+ const char* chars = path.begin();
+ for (Index i = path.getLength() - 1; i >= 0; --i)
{
- const char* chars = path.begin();
- for (Index i = path.getLength() - 1; i >= 0; --i)
+ const char c = chars[i];
+ if (c == '/' || c == '\\')
{
- const char c = chars[i];
- if (c == '/' || c == '\\')
- {
- return i;
- }
+ return i;
}
- return -1;
}
+ return -1;
+}
- /* static */Index Path::findExtIndex(UnownedStringSlice const& path)
- {
- const Index sepIndex = findLastSeparatorIndex(path);
+/* static */ Index Path::findExtIndex(UnownedStringSlice const& path)
+{
+ const Index sepIndex = findLastSeparatorIndex(path);
- const Index dotIndex = path.lastIndexOf('.');
- if (sepIndex >= 0)
- {
- // Index has to be in the last part of the path
- return (dotIndex > sepIndex) ? dotIndex : -1;
- }
- else
- {
- return dotIndex;
- }
+ const Index dotIndex = path.lastIndexOf('.');
+ if (sepIndex >= 0)
+ {
+ // Index has to be in the last part of the path
+ return (dotIndex > sepIndex) ? dotIndex : -1;
}
-
- String Path::getFileName(const String& path)
+ else
{
- Index pos = findLastSeparatorIndex(path);
- if (pos >= 0)
- {
- pos = pos + 1;
- return path.subString(pos, path.getLength() - pos);
- }
- else
- {
- return path;
- }
+ return dotIndex;
}
+}
- /* static */String Path::getFileNameWithoutExt(const String& path)
+String Path::getFileName(const String& path)
+{
+ Index pos = findLastSeparatorIndex(path);
+ if (pos >= 0)
{
- Index sepIndex = findLastSeparatorIndex(path);
- sepIndex = (sepIndex < 0) ? 0 : (sepIndex + 1);
- Index dotIndex = findExtIndex(path);
- dotIndex = (dotIndex < 0) ? path.getLength() : dotIndex;
-
- return path.subString(sepIndex, dotIndex - sepIndex);
+ pos = pos + 1;
+ return path.subString(pos, path.getLength() - pos);
}
-
- /* static*/ String Path::getPathWithoutExt(const String& path)
+ else
{
- Index dotPos = findExtIndex(path);
- if (dotPos >= 0)
- return path.subString(0, dotPos);
- else
- return path;
+ return path;
}
+}
+
+/* static */ String Path::getFileNameWithoutExt(const String& path)
+{
+ Index sepIndex = findLastSeparatorIndex(path);
+ sepIndex = (sepIndex < 0) ? 0 : (sepIndex + 1);
+ Index dotIndex = findExtIndex(path);
+ dotIndex = (dotIndex < 0) ? path.getLength() : dotIndex;
+
+ return path.subString(sepIndex, dotIndex - sepIndex);
+}
- UnownedStringSlice Path::getPathExt(const UnownedStringSlice& path)
+/* static*/ String Path::getPathWithoutExt(const String& path)
+{
+ Index dotPos = findExtIndex(path);
+ if (dotPos >= 0)
+ return path.subString(0, dotPos);
+ else
+ return path;
+}
+
+UnownedStringSlice Path::getPathExt(const UnownedStringSlice& path)
+{
+ const Index dotPos = findExtIndex(path);
+ if (dotPos >= 0)
{
- const Index dotPos = findExtIndex(path);
- if (dotPos >= 0)
- {
- return path.subString(dotPos + 1, path.getLength() - dotPos - 1);
- }
- else
- {
- // Note that the caller can identify if path has no extension or just a .
- // as if it's a dot a zero length slice is returned in path
- // If it's not then a default slice is returned (which doesn't point into path).
- //
- // Granted this is a little obscure and perhaps should be improved.
- return UnownedStringSlice();
- }
+ return path.subString(dotPos + 1, path.getLength() - dotPos - 1);
}
-
- String Path::getParentDirectory(const String& path)
+ else
{
- Index pos = findLastSeparatorIndex(path);
- if (pos >= 0)
- return path.subString(0, pos);
- else
- return "";
+ // Note that the caller can identify if path has no extension or just a .
+ // as if it's a dot a zero length slice is returned in path
+ // If it's not then a default slice is returned (which doesn't point into path).
+ //
+ // Granted this is a little obscure and perhaps should be improved.
+ return UnownedStringSlice();
}
+}
- /* static */void Path::append(StringBuilder& ioBuilder, const UnownedStringSlice& path)
+String Path::getParentDirectory(const String& path)
+{
+ Index pos = findLastSeparatorIndex(path);
+ if (pos >= 0)
+ return path.subString(0, pos);
+ else
+ return "";
+}
+
+/* static */ void Path::append(StringBuilder& ioBuilder, const UnownedStringSlice& path)
+{
+ if (ioBuilder.getLength() == 0)
{
- if (ioBuilder.getLength() == 0)
- {
- ioBuilder.append(path);
- return;
- }
- if (path.getLength() > 0)
+ ioBuilder.append(path);
+ return;
+ }
+ if (path.getLength() > 0)
+ {
+ // If ioBuilder doesn't end in a delimiter, add one
+ if (!isDelimiter(ioBuilder[ioBuilder.getLength() - 1]))
{
- // If ioBuilder doesn't end in a delimiter, add one
- if (!isDelimiter(ioBuilder[ioBuilder.getLength() - 1]))
+ // Determine the preferred delimiter to use based on existing path.
+ char preferedDelimiter = kOSCanonicalPathDelimiter;
+ if (kOSAlternativePathDelimiter != preferedDelimiter)
{
- // Determine the preferred delimiter to use based on existing path.
- char preferedDelimiter = kOSCanonicalPathDelimiter;
- if (kOSAlternativePathDelimiter != preferedDelimiter)
+ // If we found the existing path uses the alternative delimiter, we will
+ // use that instead of the canonical one.
+ constexpr Index kMaxDelimiterSearchRange = 32;
+ for (Index i = 0; i < Math::Min(kMaxDelimiterSearchRange, ioBuilder.getLength());
+ i++)
{
- // If we found the existing path uses the alternative delimiter, we will
- // use that instead of the canonical one.
- constexpr Index kMaxDelimiterSearchRange = 32;
- for (Index i = 0; i < Math::Min(kMaxDelimiterSearchRange, ioBuilder.getLength()); i++)
+ if (ioBuilder[i] == kOSAlternativePathDelimiter)
{
- if (ioBuilder[i] == kOSAlternativePathDelimiter)
- {
- preferedDelimiter = kOSAlternativePathDelimiter;
- break;
- }
+ preferedDelimiter = kOSAlternativePathDelimiter;
+ break;
}
}
- ioBuilder.append(preferedDelimiter);
}
- // Check that path doesn't start with a path delimiter
- SLANG_ASSERT(!isDelimiter(path[0]));
- // Append the path
- ioBuilder.append(path);
+ ioBuilder.append(preferedDelimiter);
}
+ // Check that path doesn't start with a path delimiter
+ SLANG_ASSERT(!isDelimiter(path[0]));
+ // Append the path
+ ioBuilder.append(path);
}
+}
- /* static */void Path::combineIntoBuilder(const UnownedStringSlice& path1, const UnownedStringSlice& path2, StringBuilder& outBuilder)
+/* static */ void Path::combineIntoBuilder(
+ const UnownedStringSlice& path1,
+ const UnownedStringSlice& path2,
+ StringBuilder& outBuilder)
+{
+ outBuilder.clear();
+ outBuilder.append(path1);
+ append(outBuilder, path2);
+}
+
+String Path::combine(const String& path1, const String& path2)
+{
+ if (path1.getLength() == 0)
{
- outBuilder.clear();
- outBuilder.append(path1);
- append(outBuilder, path2);
+ return path2;
}
- String Path::combine(const String& path1, const String& path2)
+ StringBuilder sb;
+ combineIntoBuilder(path1.getUnownedSlice(), path2.getUnownedSlice(), sb);
+ return sb.produceString();
+}
+String Path::combine(const String& path1, const String& path2, const String& path3)
+{
+ StringBuilder sb;
+ sb.append(path1);
+ append(sb, path2.getUnownedSlice());
+ append(sb, path3.getUnownedSlice());
+ return sb.produceString();
+}
+
+/* static */ bool Path::isDriveSpecification(const UnownedStringSlice& element)
+{
+ switch (element.getLength())
{
- if (path1.getLength() == 0)
+ case 0:
{
- return path2;
+ // We'll just assume it is
+ return true;
}
-
- StringBuilder sb;
- combineIntoBuilder(path1.getUnownedSlice(), path2.getUnownedSlice(), sb);
- return sb.produceString();
- }
- String Path::combine(const String& path1, const String& path2, const String& path3)
- {
- StringBuilder sb;
- sb.append(path1);
- append(sb, path2.getUnownedSlice());
- append(sb, path3.getUnownedSlice());
- return sb.produceString();
- }
-
- /* static */ bool Path::isDriveSpecification(const UnownedStringSlice& element)
- {
- switch (element.getLength())
+ case 2:
{
- case 0:
- {
- // We'll just assume it is
- return true;
- }
- case 2:
- {
- // Look for a windows like drive spec
- const char firstChar = element[0];
- return element[1] == ':' && ((firstChar >= 'a' && firstChar <= 'z') || (firstChar >= 'A' && firstChar <= 'Z'));
- }
- default: return false;
+ // Look for a windows like drive spec
+ const char firstChar = element[0];
+ return element[1] == ':' && ((firstChar >= 'a' && firstChar <= 'z') ||
+ (firstChar >= 'A' && firstChar <= 'Z'));
}
+ default: return false;
}
+}
- UnownedStringSlice Path::getFirstElement(const UnownedStringSlice& in)
- {
- const char* end = in.end();
- const char* cur = in.begin();
- // Find delimiter or the end
- while (cur < end && !Path::isDelimiter(*cur)) ++cur;
- return UnownedStringSlice(in.begin(), cur);
- }
+UnownedStringSlice Path::getFirstElement(const UnownedStringSlice& in)
+{
+ const char* end = in.end();
+ const char* cur = in.begin();
+ // Find delimiter or the end
+ while (cur < end && !Path::isDelimiter(*cur))
+ ++cur;
+ return UnownedStringSlice(in.begin(), cur);
+}
- /* static */bool Path::isAbsolute(const UnownedStringSlice& path)
+/* static */ bool Path::isAbsolute(const UnownedStringSlice& path)
+{
+ if (path.getLength() > 0 && isDelimiter(path[0]))
{
- if (path.getLength() > 0 && isDelimiter(path[0]))
- {
- return true;
- }
+ return true;
+ }
#if SLANG_WINDOWS_FAMILY
- // Check for the \\ network drive style
- if (path.getLength() >= 2 && path[0] == '\\' && path[1] == '\\')
- {
- return true;
- }
-
- // Check for drive
- if (isDriveSpecification(getFirstElement(path)))
- {
- return true;
- }
-#endif
-
- return false;
+ // Check for the \\ network drive style
+ if (path.getLength() >= 2 && path[0] == '\\' && path[1] == '\\')
+ {
+ return true;
}
- /* static */void Path::split(const UnownedStringSlice& path, List<UnownedStringSlice>& splitOut)
+ // Check for drive
+ if (isDriveSpecification(getFirstElement(path)))
{
- splitOut.clear();
+ return true;
+ }
+#endif
- const char* start = path.begin();
- const char* end = path.end();
+ return false;
+}
- while (start < end)
- {
- const char* cur = start;
- // Find the split
- while (cur < end && !isDelimiter(*cur)) cur++;
+/* static */ void Path::split(const UnownedStringSlice& path, List<UnownedStringSlice>& splitOut)
+{
+ splitOut.clear();
- splitOut.add(UnownedStringSlice(start, cur));
+ const char* start = path.begin();
+ const char* end = path.end();
- // Next
- start = cur + 1;
- }
+ while (start < end)
+ {
+ const char* cur = start;
+ // Find the split
+ while (cur < end && !isDelimiter(*cur))
+ cur++;
- // Okay if the end is empty. And we aren't with a spec like // or c:/ , then drop the final slash
- if (splitOut.getCount() > 1 && splitOut.getLast().getLength() == 0)
- {
- if (splitOut.getCount() == 2 && isDriveSpecification(splitOut[0]))
- {
- return;
- }
- // Remove the last
- splitOut.removeLast();
- }
+ splitOut.add(UnownedStringSlice(start, cur));
+
+ // Next
+ start = cur + 1;
}
- /* static */bool Path::hasRelativeElement(const UnownedStringSlice& path)
+ // Okay if the end is empty. And we aren't with a spec like // or c:/ , then drop the final
+ // slash
+ if (splitOut.getCount() > 1 && splitOut.getLast().getLength() == 0)
{
- List<UnownedStringSlice> splitPath;
- split(path, splitPath);
-
- for (const auto& cur : splitPath)
+ if (splitOut.getCount() == 2 && isDriveSpecification(splitOut[0]))
{
- if (cur == "." || cur == "..")
- {
- return true;
- }
+ return;
}
- return false;
+ // Remove the last
+ splitOut.removeLast();
}
+}
- /* static */SlangResult Path::simplify(const UnownedStringSlice& path, SimplifyStyle style, StringBuilder& outPath)
+/* static */ bool Path::hasRelativeElement(const UnownedStringSlice& path)
+{
+ List<UnownedStringSlice> splitPath;
+ split(path, splitPath);
+
+ for (const auto& cur : splitPath)
{
- if (path.getLength() == 0)
+ if (cur == "." || cur == "..")
{
- return SLANG_FAIL;
+ return true;
}
+ }
+ return false;
+}
- List<UnownedStringSlice> splitPath;
- split(UnownedStringSlice(path), splitPath);
+/* static */ SlangResult Path::simplify(
+ const UnownedStringSlice& path,
+ SimplifyStyle style,
+ StringBuilder& outPath)
+{
+ if (path.getLength() == 0)
+ {
+ return SLANG_FAIL;
+ }
- simplify(splitPath);
+ List<UnownedStringSlice> splitPath;
+ split(UnownedStringSlice(path), splitPath);
- const auto simplifyIntegral = SimplifyIntegral(style);
+ simplify(splitPath);
- // If it has a relative part then it's not absolute
- if ((simplifyIntegral & SimplifyFlag::AbsoluteOnly) &&
- splitPath.indexOf(UnownedStringSlice::fromLiteral("..")) >= 0)
- {
- return SLANG_E_NOT_FOUND;
- }
+ const auto simplifyIntegral = SimplifyIntegral(style);
- // We allow splitPath.getCount() == 0, because
- // the original path could have been '.' or './.'
- //
- // Special handling this case is in Path::join
+ // If it has a relative part then it's not absolute
+ if ((simplifyIntegral & SimplifyFlag::AbsoluteOnly) &&
+ splitPath.indexOf(UnownedStringSlice::fromLiteral("..")) >= 0)
+ {
+ return SLANG_E_NOT_FOUND;
+ }
- // If we want the path produced such that is *not* output with a root (ie SimplifyFlag::NoRoot)
- // we detect if we a rooted path (ie in effect starting with "/") and so splitPath[0] == ""
- // and remove that part from when doing the join.
- if ((simplifyIntegral & SimplifyFlag::NoRoot) &&
- (splitPath.getCount() && splitPath[0].getLength() == 0))
- {
- // If we allow without a root, we remove from the join
- Path::join(splitPath.getBuffer() + 1, splitPath.getCount() - 1, outPath);
- }
- else
- {
- Path::join(splitPath.getBuffer(), splitPath.getCount(), outPath);
- }
+ // We allow splitPath.getCount() == 0, because
+ // the original path could have been '.' or './.'
+ //
+ // Special handling this case is in Path::join
- return SLANG_OK;
+ // If we want the path produced such that is *not* output with a root (ie SimplifyFlag::NoRoot)
+ // we detect if we a rooted path (ie in effect starting with "/") and so splitPath[0] == ""
+ // and remove that part from when doing the join.
+ if ((simplifyIntegral & SimplifyFlag::NoRoot) &&
+ (splitPath.getCount() && splitPath[0].getLength() == 0))
+ {
+ // If we allow without a root, we remove from the join
+ Path::join(splitPath.getBuffer() + 1, splitPath.getCount() - 1, outPath);
}
-
- /* static */void Path::simplify(List<UnownedStringSlice>& ioSplit)
+ else
{
- // Strictly speaking we could do something about case on platforms like window, but here we won't worry about that
- for (Index i = 0; i < ioSplit.getCount(); i++)
- {
- const UnownedStringSlice& cur = ioSplit[i];
- if (cur == "." && ioSplit.getCount() > 1)
- {
- // Just remove it
- ioSplit.removeAt(i);
- i--;
- }
- else if (cur == ".." && i > 0)
- {
- // Can we remove this and the one before ?
- UnownedStringSlice& before = ioSplit[i - 1];
- if (before == ".." || (i == 1 && isDriveSpecification(before)))
- {
- // Can't do it, but we allow relative, so just leave for now
- continue;
- }
- ioSplit.removeRange(i - 1, 2);
- i -= 2;
- }
- }
+ Path::join(splitPath.getBuffer(), splitPath.getCount(), outPath);
}
- /* static */void Path::join(const UnownedStringSlice* slices, Index count, StringBuilder& out)
- {
- out.clear();
+ return SLANG_OK;
+}
- if (count == 0)
- {
- out << ".";
- }
- else if (count == 1 && slices[0].getLength() == 0)
+/* static */ void Path::simplify(List<UnownedStringSlice>& ioSplit)
+{
+ // Strictly speaking we could do something about case on platforms like window, but here we
+ // won't worry about that
+ for (Index i = 0; i < ioSplit.getCount(); i++)
+ {
+ const UnownedStringSlice& cur = ioSplit[i];
+ if (cur == "." && ioSplit.getCount() > 1)
{
- // It's the root
- out << kPathDelimiter;
+ // Just remove it
+ ioSplit.removeAt(i);
+ i--;
}
- else
+ else if (cur == ".." && i > 0)
{
- StringUtil::join(slices, count, kPathDelimiter, out);
+ // Can we remove this and the one before ?
+ UnownedStringSlice& before = ioSplit[i - 1];
+ if (before == ".." || (i == 1 && isDriveSpecification(before)))
+ {
+ // Can't do it, but we allow relative, so just leave for now
+ continue;
+ }
+ ioSplit.removeRange(i - 1, 2);
+ i -= 2;
}
}
+}
+/* static */ void Path::join(const UnownedStringSlice* slices, Index count, StringBuilder& out)
+{
+ out.clear();
- /* static */String Path::simplify(const UnownedStringSlice& path)
+ if (count == 0)
{
- List<UnownedStringSlice> splitPath;
- split(path, splitPath);
- simplify(splitPath);
-
- // Reconstruct the string
- StringBuilder builder;
- join(splitPath.getBuffer(), splitPath.getCount(), builder);
- return builder.toString();
+ out << ".";
}
-
- bool Path::createDirectory(const String& path)
+ else if (count == 1 && slices[0].getLength() == 0)
+ {
+ // It's the root
+ out << kPathDelimiter;
+ }
+ else
{
+ StringUtil::join(slices, count, kPathDelimiter, out);
+ }
+}
+
+
+/* static */ String Path::simplify(const UnownedStringSlice& path)
+{
+ List<UnownedStringSlice> splitPath;
+ split(path, splitPath);
+ simplify(splitPath);
+
+ // Reconstruct the string
+ StringBuilder builder;
+ join(splitPath.getBuffer(), splitPath.getCount(), builder);
+ return builder.toString();
+}
+
+bool Path::createDirectory(const String& path)
+{
#if defined(_WIN32)
- return _wmkdir(path.toWString()) == 0;
+ return _wmkdir(path.toWString()) == 0;
#else
- return mkdir(path.getBuffer(), 0777) == 0;
+ return mkdir(path.getBuffer(), 0777) == 0;
#endif
- }
+}
- bool Path::createDirectoryRecursive(const String& path)
+bool Path::createDirectoryRecursive(const String& path)
+{
+ String finalPath = Path::simplify(path);
+ if (finalPath.getLength() == 0)
{
- String finalPath = Path::simplify(path);
- if (finalPath.getLength() == 0)
- {
- return false;
- }
-
- List<String> pathList;
-
- // Check whether the parent directories exist, and add to the pathList if they are
- // not, we will create all the directories from back of the list.
- String parentDir = finalPath;
- for(;;)
- {
- if (parentDir.getLength() == 0 || File::exists(parentDir))
- {
- break;
- }
- else
- {
- pathList.add(parentDir);
- parentDir = Path::getParentDirectory(parentDir);
- }
- }
+ return false;
+ }
- // If there are no directories to create, then we are done
- if (pathList.getCount() == 0)
- {
- return true;
- }
+ List<String> pathList;
- // Traverse from back of the list, because that is most outer directory.
- Int i = 0;
- for (i = pathList.getCount() - 1; i >= 0; i--)
+ // Check whether the parent directories exist, and add to the pathList if they are
+ // not, we will create all the directories from back of the list.
+ String parentDir = finalPath;
+ for (;;)
+ {
+ if (parentDir.getLength() == 0 || File::exists(parentDir))
{
- if (!createDirectory(pathList[i]))
- {
- break;
- }
+ break;
}
-
- // Something wrong when creating parent directories
- if (i > 0)
+ else
{
- // Remove the directories if we've created
- if (i != pathList.getCount() - 1)
- remove(pathList[i]);
-
- return false;
+ pathList.add(parentDir);
+ parentDir = Path::getParentDirectory(parentDir);
}
+ }
+ // If there are no directories to create, then we are done
+ if (pathList.getCount() == 0)
+ {
return true;
}
- /* static */SlangResult Path::getPathType(const String& path, SlangPathType* pathTypeOut)
+ // Traverse from back of the list, because that is most outer directory.
+ Int i = 0;
+ for (i = pathList.getCount() - 1; i >= 0; i--)
{
-#ifdef _WIN32
- // https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx
- struct _stat32 statVar;
- if (::_wstat32(String(path).toWString(), &statVar) == 0)
+ if (!createDirectory(pathList[i]))
{
- if (statVar.st_mode & _S_IFDIR)
- {
- *pathTypeOut = SLANG_PATH_TYPE_DIRECTORY;
- return SLANG_OK;
- }
- else if (statVar.st_mode & _S_IFREG)
- {
- *pathTypeOut = SLANG_PATH_TYPE_FILE;
- return SLANG_OK;
- }
- return SLANG_FAIL;
+ break;
}
+ }
- return SLANG_E_NOT_FOUND;
-#else
- struct stat statVar;
- if (::stat(path.getBuffer(), &statVar) == 0)
- {
- if (S_ISDIR(statVar.st_mode))
- {
- *pathTypeOut = SLANG_PATH_TYPE_DIRECTORY;
- return SLANG_OK;
- }
- if (S_ISREG(statVar.st_mode))
- {
- *pathTypeOut = SLANG_PATH_TYPE_FILE;
- return SLANG_OK;
- }
- return SLANG_FAIL;
- }
+ // Something wrong when creating parent directories
+ if (i > 0)
+ {
+ // Remove the directories if we've created
+ if (i != pathList.getCount() - 1)
+ remove(pathList[i]);
- return SLANG_E_NOT_FOUND;
-#endif
+ return false;
}
+ return true;
+}
- /* static */SlangResult Path::getCanonical(const String& path, String& canonicalPathOut)
+/* static */ SlangResult Path::getPathType(const String& path, SlangPathType* pathTypeOut)
+{
+#ifdef _WIN32
+ // https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx
+ struct _stat32 statVar;
+ if (::_wstat32(String(path).toWString(), &statVar) == 0)
{
-#if defined(_WIN32)
- // https://msdn.microsoft.com/en-us/library/506720ff.aspx
- wchar_t* absPath = ::_wfullpath(nullptr, path.toWString(), 0);
- if (!absPath)
+ if (statVar.st_mode & _S_IFDIR)
{
- return SLANG_FAIL;
+ *pathTypeOut = SLANG_PATH_TYPE_DIRECTORY;
+ return SLANG_OK;
}
-
- canonicalPathOut = String::fromWString(absPath);
- ::free(absPath);
- return SLANG_OK;
-#else
-# if 1
-
- // http://man7.org/linux/man-pages/man3/realpath.3.html
- char* canonicalPath = ::realpath(path.begin(), nullptr);
- if (canonicalPath)
+ else if (statVar.st_mode & _S_IFREG)
{
- canonicalPathOut = canonicalPath;
- ::free(canonicalPath);
+ *pathTypeOut = SLANG_PATH_TYPE_FILE;
return SLANG_OK;
}
return SLANG_FAIL;
-# else
- // This is a mechanism to get an approximation of canonical path if we don't have 'realpath'
- // We only can get if the file exists. This checks that the ../. etc are really valid
- SlangPathType pathType;
- SLANG_RETURN_ON_FAIL(getPathType(path, &pathType));
- if (isAbsolute(path))
+ }
+
+ return SLANG_E_NOT_FOUND;
+#else
+ struct stat statVar;
+ if (::stat(path.getBuffer(), &statVar) == 0)
+ {
+ if (S_ISDIR(statVar.st_mode))
{
- // If it's absolute, we can just simplify as is
- canonicalPathOut = Path::simplify(path);
+ *pathTypeOut = SLANG_PATH_TYPE_DIRECTORY;
return SLANG_OK;
}
- else
+ if (S_ISREG(statVar.st_mode))
{
- char buffer[PATH_MAX];
- // https://linux.die.net/man/3/getcwd
- const char* getCwdPath = getcwd(buffer, SLANG_COUNT_OF(buffer));
- if (!getCwdPath)
- {
- return SLANG_FAIL;
- }
-
- // Okay combine the paths
- String combinedPaths = Path::combine(String(getCwdPath), path);
- // Simplify
- canonicalPathOut = Path::simplify(combinedPaths);
+ *pathTypeOut = SLANG_PATH_TYPE_FILE;
return SLANG_OK;
}
-# endif
-#endif
+ return SLANG_FAIL;
}
- String Path::getCurrentPath()
+ return SLANG_E_NOT_FOUND;
+#endif
+}
+
+
+/* static */ SlangResult Path::getCanonical(const String& path, String& canonicalPathOut)
+{
+#if defined(_WIN32)
+ // https://msdn.microsoft.com/en-us/library/506720ff.aspx
+ wchar_t* absPath = ::_wfullpath(nullptr, path.toWString(), 0);
+ if (!absPath)
{
- Slang::String path;
- getCanonical(".", path);
- return path;
+ return SLANG_FAIL;
}
- String Path::getRelativePath(String base, String path)
+ canonicalPathOut = String::fromWString(absPath);
+ ::free(absPath);
+ return SLANG_OK;
+#else
+#if 1
+
+ // http://man7.org/linux/man-pages/man3/realpath.3.html
+ char* canonicalPath = ::realpath(path.begin(), nullptr);
+ if (canonicalPath)
{
- std::filesystem::path p1(base.getBuffer());
- std::filesystem::path p2(path.getBuffer());
- std::error_code ec;
- auto result = std::filesystem::relative(p2, p1, ec);
- if (ec)
- return path;
- return String(UnownedStringSlice(result.generic_u8string().c_str()));
+ canonicalPathOut = canonicalPath;
+ ::free(canonicalPath);
+ return SLANG_OK;
}
-
- SlangResult Path::remove(const String& path)
+ return SLANG_FAIL;
+#else
+ // This is a mechanism to get an approximation of canonical path if we don't have 'realpath'
+ // We only can get if the file exists. This checks that the ../. etc are really valid
+ SlangPathType pathType;
+ SLANG_RETURN_ON_FAIL(getPathType(path, &pathType));
+ if (isAbsolute(path))
+ {
+ // If it's absolute, we can just simplify as is
+ canonicalPathOut = Path::simplify(path);
+ return SLANG_OK;
+ }
+ else
{
+ char buffer[PATH_MAX];
+ // https://linux.die.net/man/3/getcwd
+ const char* getCwdPath = getcwd(buffer, SLANG_COUNT_OF(buffer));
+ if (!getCwdPath)
+ {
+ return SLANG_FAIL;
+ }
+
+ // Okay combine the paths
+ String combinedPaths = Path::combine(String(getCwdPath), path);
+ // Simplify
+ canonicalPathOut = Path::simplify(combinedPaths);
+ return SLANG_OK;
+ }
+#endif
+#endif
+}
+
+String Path::getCurrentPath()
+{
+ Slang::String path;
+ getCanonical(".", path);
+ return path;
+}
+
+String Path::getRelativePath(String base, String path)
+{
+ std::filesystem::path p1(base.getBuffer());
+ std::filesystem::path p2(path.getBuffer());
+ std::error_code ec;
+ auto result = std::filesystem::relative(p2, p1, ec);
+ if (ec)
+ return path;
+ return String(UnownedStringSlice(result.generic_u8string().c_str()));
+}
+
+SlangResult Path::remove(const String& path)
+{
#ifdef _WIN32
- // Need to determine if its a file or directory
+ // Need to determine if its a file or directory
- SlangPathType pathType;
- SLANG_RETURN_ON_FAIL(getPathType(path, &pathType));
+ SlangPathType pathType;
+ SLANG_RETURN_ON_FAIL(getPathType(path, &pathType));
- switch (pathType)
+ switch (pathType)
+ {
+ case SLANG_PATH_TYPE_FILE:
{
- case SLANG_PATH_TYPE_FILE:
+ // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-deletefilea
+ if (DeleteFileA(path.getBuffer()))
{
- // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-deletefilea
- if (DeleteFileA(path.getBuffer()))
- {
- return SLANG_OK;
- }
- break;
+ return SLANG_OK;
}
- case SLANG_PATH_TYPE_DIRECTORY:
+ break;
+ }
+ case SLANG_PATH_TYPE_DIRECTORY:
+ {
+ // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-removedirectorya
+ if (RemoveDirectoryA(path.getBuffer()))
{
- // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-removedirectorya
- if (RemoveDirectoryA(path.getBuffer()))
- {
- return SLANG_OK;
- }
- break;
+ return SLANG_OK;
}
- default: break;
+ break;
}
+ default: break;
+ }
- return SLANG_FAIL;
+ return SLANG_FAIL;
#else
- // https://linux.die.net/man/3/remove
- if (::remove(path.getBuffer()) == 0)
- {
- return SLANG_OK;
- }
- return SLANG_FAIL;
-#endif
+ // https://linux.die.net/man/3/remove
+ if (::remove(path.getBuffer()) == 0)
+ {
+ return SLANG_OK;
}
+ return SLANG_FAIL;
+#endif
+}
- /* static */SlangResult Path::removeNonEmpty(const String& path)
+/* static */ SlangResult Path::removeNonEmpty(const String& path)
+{
+ if (File::exists(path) == false)
{
- if (File::exists(path) == false)
- {
- return SLANG_OK;
- }
+ return SLANG_OK;
+ }
- StringBuilder msgBuilder;
- // Path::remove() doesn't support remove a non-empty directory, so we need to implement
- // a simple function to remove the directory recursively.
+ StringBuilder msgBuilder;
+ // Path::remove() doesn't support remove a non-empty directory, so we need to implement
+ // a simple function to remove the directory recursively.
#ifdef _WIN32
- // https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shfileoperationa
- // Note: the fromPath requires a double-null-terminated string.
- String newPath = path;
- newPath.append('\0');
- SHFILEOPSTRUCTA file_op = {
- NULL,
- FO_DELETE,
- newPath.begin(),
- nullptr,
- FOF_NOCONFIRMATION |
- FOF_NOERRORUI |
- FOF_SILENT,
- false,
- 0,
- nullptr };
- int ret = SHFileOperationA(&file_op);
- if (ret)
- {
- return SLANG_FAIL;
- }
+ // https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shfileoperationa
+ // Note: the fromPath requires a double-null-terminated string.
+ String newPath = path;
+ newPath.append('\0');
+ SHFILEOPSTRUCTA file_op = {
+ NULL,
+ FO_DELETE,
+ newPath.begin(),
+ nullptr,
+ FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT,
+ false,
+ 0,
+ nullptr};
+ int ret = SHFileOperationA(&file_op);
+ if (ret)
+ {
+ return SLANG_FAIL;
+ }
#else
- auto unlink_cb = [](const char* fpath, const struct stat* sb, int typeflag, struct FTW* ftwbuf) -> int
- {
- SLANG_UNUSED(sb)
- SLANG_UNUSED(typeflag)
- SLANG_UNUSED(ftwbuf)
- int rv = ::remove(fpath);
- if (rv)
- {
- perror(fpath);
- }
- return rv;
- };
- // https://linux.die.net/man/3/nftw
- int ret = ::nftw(path.begin(), unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
- if (ret)
- {
- return SLANG_FAIL;
- }
+ auto unlink_cb =
+ [](const char* fpath, const struct stat* sb, int typeflag, struct FTW* ftwbuf) -> int
+ {
+ SLANG_UNUSED(sb)
+ SLANG_UNUSED(typeflag)
+ SLANG_UNUSED(ftwbuf)
+ int rv = ::remove(fpath);
+ if (rv)
+ {
+ perror(fpath);
+ }
+ return rv;
+ };
+ // https://linux.die.net/man/3/nftw
+ int ret = ::nftw(path.begin(), unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
+ if (ret)
+ {
+ return SLANG_FAIL;
+ }
#endif
- return SLANG_OK;
- }
+ return SLANG_OK;
+}
#if defined(_WIN32)
- /* static */SlangResult Path::find(const String& directoryPath, const char* pattern, Visitor* visitor)
- {
- pattern = pattern ? pattern : "*";
- String searchPath = Path::combine(directoryPath, pattern);
+/* static */ SlangResult Path::find(
+ const String& directoryPath,
+ const char* pattern,
+ Visitor* visitor)
+{
+ pattern = pattern ? pattern : "*";
+ String searchPath = Path::combine(directoryPath, pattern);
- WIN32_FIND_DATAW fileData;
+ WIN32_FIND_DATAW fileData;
- HANDLE findHandle = FindFirstFileW(searchPath.toWString(), &fileData);
- if (findHandle == INVALID_HANDLE_VALUE)
- {
- return SLANG_E_NOT_FOUND;
- }
+ HANDLE findHandle = FindFirstFileW(searchPath.toWString(), &fileData);
+ if (findHandle == INVALID_HANDLE_VALUE)
+ {
+ return SLANG_E_NOT_FOUND;
+ }
- do
+ do
+ {
+ if (!((wcscmp(fileData.cFileName, L".") == 0) || (wcscmp(fileData.cFileName, L"..") == 0)))
{
- if (!((wcscmp(fileData.cFileName, L".") == 0) ||
- (wcscmp(fileData.cFileName, L"..") == 0)))
- {
- const Type type = (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? Type::Directory : Type::File;
+ const Type type = (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ ? Type::Directory
+ : Type::File;
- String filename = String::fromWString(fileData.cFileName);
- visitor->accept(type, filename.getUnownedSlice());
- }
+ String filename = String::fromWString(fileData.cFileName);
+ visitor->accept(type, filename.getUnownedSlice());
}
- while (FindNextFileW(findHandle, &fileData) != 0);
+ } while (FindNextFileW(findHandle, &fileData) != 0);
- ::FindClose(findHandle);
- return SLANG_OK;
- }
+ ::FindClose(findHandle);
+ return SLANG_OK;
+}
#else
- /* static */SlangResult Path::find(const String& directoryPath, const char* pattern, Visitor* visitor)
+/* static */ SlangResult Path::find(
+ const String& directoryPath,
+ const char* pattern,
+ Visitor* visitor)
+{
+ DIR* directory = opendir(directoryPath.getBuffer());
+
+ if (!directory)
{
- DIR* directory = opendir(directoryPath.getBuffer());
+ return SLANG_E_NOT_FOUND;
+ }
- if (!directory)
+ StringBuilder builder;
+ for (;;)
+ {
+ dirent* entry = readdir(directory);
+ if (entry == nullptr)
{
- return SLANG_E_NOT_FOUND;
+ break;
}
- StringBuilder builder;
- for (;;)
+ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
{
- dirent* entry = readdir(directory);
- if (entry == nullptr)
- {
- break;
- }
-
- if (strcmp(entry->d_name, ".") == 0 ||
- strcmp(entry->d_name, "..") == 0)
- {
- continue;
- }
+ continue;
+ }
- // If there is a pattern, check if it matches, and if it doesn't ignore it
- if (pattern && fnmatch(pattern, entry->d_name, 0) != 0)
- {
- continue;
- }
+ // If there is a pattern, check if it matches, and if it doesn't ignore it
+ if (pattern && fnmatch(pattern, entry->d_name, 0) != 0)
+ {
+ continue;
+ }
- const UnownedStringSlice filename(entry->d_name);
+ const UnownedStringSlice filename(entry->d_name);
- // Produce the full path, to do stat
- Path::combineIntoBuilder(directoryPath.getUnownedSlice(), filename, builder);
+ // Produce the full path, to do stat
+ Path::combineIntoBuilder(directoryPath.getUnownedSlice(), filename, builder);
- // fprintf(stderr, "stat(%s)\n", path.getBuffer());
- struct stat fileInfo;
- if (stat(builder.getBuffer(), &fileInfo) != 0)
- {
- continue;
- }
-
- Type type = Type::Unknown;
- if (S_ISDIR(fileInfo.st_mode))
- {
- type = Type::Directory;
- }
- else if (S_ISREG(fileInfo.st_mode))
- {
- type = Type::File;
- }
+ // fprintf(stderr, "stat(%s)\n", path.getBuffer());
+ struct stat fileInfo;
+ if (stat(builder.getBuffer(), &fileInfo) != 0)
+ {
+ continue;
+ }
- visitor->accept(type, filename);
+ Type type = Type::Unknown;
+ if (S_ISDIR(fileInfo.st_mode))
+ {
+ type = Type::Directory;
+ }
+ else if (S_ISREG(fileInfo.st_mode))
+ {
+ type = Type::File;
}
- closedir(directory);
- return SLANG_OK;
+ visitor->accept(type, filename);
}
+
+ closedir(directory);
+ return SLANG_OK;
+}
#endif
- bool Path::equals(String path1, String path2)
- {
- Path::getCanonical(path1, path1);
- Path::getCanonical(path2, path2);
+bool Path::equals(String path1, String path2)
+{
+ Path::getCanonical(path1, path1);
+ Path::getCanonical(path2, path2);
#if SLANG_WINDOWS_FAMILY
- return path1.getUnownedSlice().caseInsensitiveEquals(path2.getUnownedSlice());
+ return path1.getUnownedSlice().caseInsensitiveEquals(path2.getUnownedSlice());
#else
- return path1 == path2;
+ return path1 == path2;
#endif
- }
+}
- /// Gets the path to the executable that was invoked that led to the current threads execution
- /// If run from a shared library/dll will be the path of the executable that loaded said library
- /// @param outPath Pointer to buffer to hold the path.
- /// @param ioPathSize Size of the buffer to hold the path (including zero terminator).
- /// @return SLANG_OK on success, SLANG_E_BUFFER_TOO_SMALL if buffer is too small. If ioPathSize is changed it will be the required size
- static SlangResult _calcExectuablePath(char* outPath, size_t* ioSize)
- {
- SLANG_ASSERT(ioSize);
- const size_t bufferSize = *ioSize;
- SLANG_ASSERT(bufferSize > 0);
+/// Gets the path to the executable that was invoked that led to the current threads execution
+/// If run from a shared library/dll will be the path of the executable that loaded said library
+/// @param outPath Pointer to buffer to hold the path.
+/// @param ioPathSize Size of the buffer to hold the path (including zero terminator).
+/// @return SLANG_OK on success, SLANG_E_BUFFER_TOO_SMALL if buffer is too small. If ioPathSize is
+/// changed it will be the required size
+static SlangResult _calcExectuablePath(char* outPath, size_t* ioSize)
+{
+ SLANG_ASSERT(ioSize);
+ const size_t bufferSize = *ioSize;
+ SLANG_ASSERT(bufferSize > 0);
#if SLANG_WINDOWS_FAMILY
- // https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-getmodulefilenamea
+ // https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-getmodulefilenamea
- DWORD res = ::GetModuleFileNameA(::GetModuleHandle(nullptr), outPath, DWORD(bufferSize));
- // If it fits it's the size not including terminator. So must be less than bufferSize
- if (res < bufferSize)
- {
- return SLANG_OK;
- }
- return SLANG_E_BUFFER_TOO_SMALL;
+ DWORD res = ::GetModuleFileNameA(::GetModuleHandle(nullptr), outPath, DWORD(bufferSize));
+ // If it fits it's the size not including terminator. So must be less than bufferSize
+ if (res < bufferSize)
+ {
+ return SLANG_OK;
+ }
+ return SLANG_E_BUFFER_TOO_SMALL;
#elif SLANG_LINUX_FAMILY
-# if defined(__linux__) || defined(__CYGWIN__)
- // https://linux.die.net/man/2/readlink
- // Mark last byte with 0, so can check overrun
- ssize_t resSize = ::readlink("/proc/self/exe", outPath, bufferSize);
- if (resSize < 0)
- {
- return SLANG_FAIL;
- }
- if (size_t(resSize) >= bufferSize)
- {
- return SLANG_E_BUFFER_TOO_SMALL;
- }
- // Zero terminate
- outPath[resSize - 1] = 0;
- return SLANG_OK;
-# else
- String text = Slang::File::readAllText("/proc/self/maps");
- Index startIndex = text.indexOf('/');
- if (startIndex == Index(-1))
- {
- return SLANG_FAIL;
- }
- Index endIndex = text.indexOf("\n", startIndex);
- endIndex = (endIndex == Index(-1)) ? text.getLength() : endIndex;
+#if defined(__linux__) || defined(__CYGWIN__)
+ // https://linux.die.net/man/2/readlink
+ // Mark last byte with 0, so can check overrun
+ ssize_t resSize = ::readlink("/proc/self/exe", outPath, bufferSize);
+ if (resSize < 0)
+ {
+ return SLANG_FAIL;
+ }
+ if (size_t(resSize) >= bufferSize)
+ {
+ return SLANG_E_BUFFER_TOO_SMALL;
+ }
+ // Zero terminate
+ outPath[resSize - 1] = 0;
+ return SLANG_OK;
+#else
+ String text = Slang::File::readAllText("/proc/self/maps");
+ Index startIndex = text.indexOf('/');
+ if (startIndex == Index(-1))
+ {
+ return SLANG_FAIL;
+ }
+ Index endIndex = text.indexOf("\n", startIndex);
+ endIndex = (endIndex == Index(-1)) ? text.getLength() : endIndex;
- auto path = text.subString(startIndex, endIndex - startIndex);
+ auto path = text.subString(startIndex, endIndex - startIndex);
- if (path.getLength() < bufferSize)
- {
- ::memcpy(outPath, path.begin(), path.getLength());
- outPath[path.getLength()] = 0;
- return SLANG_OK;
- }
+ if (path.getLength() < bufferSize)
+ {
+ ::memcpy(outPath, path.begin(), path.getLength());
+ outPath[path.getLength()] = 0;
+ return SLANG_OK;
+ }
- *ioSize = path.getLength() + 1;
- return SLANG_E_BUFFER_TOO_SMALL;
-# endif
+ *ioSize = path.getLength() + 1;
+ return SLANG_E_BUFFER_TOO_SMALL;
+#endif
#elif SLANG_APPLE_FAMILY
- // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dyld.3.html
- uint32_t size = uint32_t(*ioSize);
- switch (_NSGetExecutablePath(outPath, &size))
+ // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dyld.3.html
+ uint32_t size = uint32_t(*ioSize);
+ switch (_NSGetExecutablePath(outPath, &size))
+ {
+ case 0: return SLANG_OK;
+ case -1:
{
- case 0: return SLANG_OK;
- case -1:
- {
- *ioSize = size;
- return SLANG_E_BUFFER_TOO_SMALL;
- }
- default: break;
+ *ioSize = size;
+ return SLANG_E_BUFFER_TOO_SMALL;
}
- return SLANG_FAIL;
+ default: break;
+ }
+ return SLANG_FAIL;
#else
- SLANG_UNUSED(outPath);
- return SLANG_E_NOT_IMPLEMENTED;
+ SLANG_UNUSED(outPath);
+ return SLANG_E_NOT_IMPLEMENTED;
#endif
- }
+}
- static String _getExecutablePath()
+static String _getExecutablePath()
+{
+ List<char> buffer;
+ // Guess an initial buffer size
+ buffer.setCount(1024);
+
+ while (true)
{
- List<char> buffer;
- // Guess an initial buffer size
- buffer.setCount(1024);
+ const size_t size = size_t(buffer.getCount());
+ size_t bufferSize = size;
+ SlangResult res = _calcExectuablePath(buffer.getBuffer(), &bufferSize);
- while (true)
+ if (SLANG_SUCCEEDED(res))
{
- const size_t size = size_t(buffer.getCount());
- size_t bufferSize = size;
- SlangResult res = _calcExectuablePath(buffer.getBuffer(), &bufferSize);
-
- if (SLANG_SUCCEEDED(res))
- {
- return String(buffer.getBuffer());
- }
-
- if (res != SLANG_E_BUFFER_TOO_SMALL)
- {
- // Couldn't determine the executable string
- return String();
- }
-
- // If bufferSize changed it should be the exact fit size, else we just make the buffer bigger by a guess (50% bigger)
- bufferSize = (bufferSize > size) ? bufferSize : (bufferSize + bufferSize / 2);
- buffer.setCount(Index(bufferSize));
+ return String(buffer.getBuffer());
}
- }
-
- /* static */String Path::getExecutablePath()
- {
- // TODO(JS): It would be better if we lazily evaluated this, and then returned the same string on subsequent calls, because it has to do
- // a fair amount of work depending on target.
- // This was how previous code worked, with a static variable. Unfortunately this led to a memory leak being reported - because reporting
- // is done before a global variable is released.
- // It would be good to have a mechanism that allows 'core' library source free memory in some controlled manner.
- return _getExecutablePath();
- }
-
- SlangResult File::readAllText(const Slang::String& fileName, String& outText)
- {
- RefPtr<FileStream> stream(new FileStream);
- SLANG_RETURN_ON_FAIL(stream->init(fileName, FileMode::Open, FileAccess::Read, FileShare::ReadWrite));
- StreamReader reader;
- SLANG_RETURN_ON_FAIL(reader.init(stream));
- SLANG_RETURN_ON_FAIL(reader.readToEnd(outText));
+ if (res != SLANG_E_BUFFER_TOO_SMALL)
+ {
+ // Couldn't determine the executable string
+ return String();
+ }
- return SLANG_OK;
+ // If bufferSize changed it should be the exact fit size, else we just make the buffer
+ // bigger by a guess (50% bigger)
+ bufferSize = (bufferSize > size) ? bufferSize : (bufferSize + bufferSize / 2);
+ buffer.setCount(Index(bufferSize));
}
+}
- SlangResult File::readAllBytes(const Slang::String& path, Slang::List<unsigned char>& out)
- {
- FileStream stream;
- SLANG_RETURN_ON_FAIL(stream.init(path, FileMode::Open, FileAccess::Read, FileShare::ReadWrite));
+/* static */ String Path::getExecutablePath()
+{
+ // TODO(JS): It would be better if we lazily evaluated this, and then returned the same string
+ // on subsequent calls, because it has to do a fair amount of work depending on target. This was
+ // how previous code worked, with a static variable. Unfortunately this led to a memory leak
+ // being reported - because reporting is done before a global variable is released. It would be
+ // good to have a mechanism that allows 'core' library source free memory in some controlled
+ // manner.
+ return _getExecutablePath();
+}
- const Int64 start = stream.getPosition();
- stream.seek(SeekOrigin::End, 0);
- const Int64 end = stream.getPosition();
- stream.seek(SeekOrigin::Start, start);
+SlangResult File::readAllText(const Slang::String& fileName, String& outText)
+{
+ RefPtr<FileStream> stream(new FileStream);
+ SLANG_RETURN_ON_FAIL(
+ stream->init(fileName, FileMode::Open, FileAccess::Read, FileShare::ReadWrite));
- const Int64 positionSizeInBytes = end - start;
+ StreamReader reader;
+ SLANG_RETURN_ON_FAIL(reader.init(stream));
+ SLANG_RETURN_ON_FAIL(reader.readToEnd(outText));
- if (UInt64(positionSizeInBytes) > UInt64(kMaxIndex))
- {
- // It's too large to fit in memory.
- return SLANG_FAIL;
- }
+ return SLANG_OK;
+}
- const Index sizeInBytes = Index(positionSizeInBytes);
+SlangResult File::readAllBytes(const Slang::String& path, Slang::List<unsigned char>& out)
+{
+ FileStream stream;
+ SLANG_RETURN_ON_FAIL(stream.init(path, FileMode::Open, FileAccess::Read, FileShare::ReadWrite));
- out.setCount(sizeInBytes);
+ const Int64 start = stream.getPosition();
+ stream.seek(SeekOrigin::End, 0);
+ const Int64 end = stream.getPosition();
+ stream.seek(SeekOrigin::Start, start);
- size_t readSizeInBytes;
- SLANG_RETURN_ON_FAIL(stream.read(out.getBuffer(), sizeInBytes, readSizeInBytes));
+ const Int64 positionSizeInBytes = end - start;
- // If not all read just return an error
- return (size_t(sizeInBytes) == readSizeInBytes) ? SLANG_OK : SLANG_FAIL;
+ if (UInt64(positionSizeInBytes) > UInt64(kMaxIndex))
+ {
+ // It's too large to fit in memory.
+ return SLANG_FAIL;
}
- SlangResult File::readAllBytes(const String& path, ScopedAllocation& out)
- {
- FileStream stream;
- SLANG_RETURN_ON_FAIL(stream.init(path, FileMode::Open, FileAccess::Read, FileShare::ReadWrite));
+ const Index sizeInBytes = Index(positionSizeInBytes);
- const Int64 start = stream.getPosition();
- stream.seek(SeekOrigin::End, 0);
- const Int64 end = stream.getPosition();
- stream.seek(SeekOrigin::Start, start);
+ out.setCount(sizeInBytes);
- const Int64 positionSizeInBytes = end - start;
+ size_t readSizeInBytes;
+ SLANG_RETURN_ON_FAIL(stream.read(out.getBuffer(), sizeInBytes, readSizeInBytes));
- if (UInt64(positionSizeInBytes) > UInt64(~size_t(0)))
- {
- // It's too large to fit in memory.
- return SLANG_FAIL;
- }
+ // If not all read just return an error
+ return (size_t(sizeInBytes) == readSizeInBytes) ? SLANG_OK : SLANG_FAIL;
+}
- const size_t sizeInBytes = size_t(positionSizeInBytes);
+SlangResult File::readAllBytes(const String& path, ScopedAllocation& out)
+{
+ FileStream stream;
+ SLANG_RETURN_ON_FAIL(stream.init(path, FileMode::Open, FileAccess::Read, FileShare::ReadWrite));
- void* data = out.allocateTerminated(sizeInBytes);
- if (!data)
- {
- return SLANG_E_OUT_OF_MEMORY;
- }
+ const Int64 start = stream.getPosition();
+ stream.seek(SeekOrigin::End, 0);
+ const Int64 end = stream.getPosition();
+ stream.seek(SeekOrigin::Start, start);
- size_t readSizeInBytes;
- SLANG_RETURN_ON_FAIL(stream.read(data, sizeInBytes, readSizeInBytes));
+ const Int64 positionSizeInBytes = end - start;
- // If not all read just return an error
- return (sizeInBytes == readSizeInBytes) ? SLANG_OK : SLANG_FAIL;
+ if (UInt64(positionSizeInBytes) > UInt64(~size_t(0)))
+ {
+ // It's too large to fit in memory.
+ return SLANG_FAIL;
}
- SlangResult File::writeAllBytes(const String& path, const void* data, size_t size)
+ const size_t sizeInBytes = size_t(positionSizeInBytes);
+
+ void* data = out.allocateTerminated(sizeInBytes);
+ if (!data)
{
- FileStream stream;
- SLANG_RETURN_ON_FAIL(stream.init(path, FileMode::Create, FileAccess::Write, FileShare::ReadWrite));
- SLANG_RETURN_ON_FAIL(stream.write(data, size));
- return SLANG_OK;
+ return SLANG_E_OUT_OF_MEMORY;
}
- SlangResult File::writeAllText(const Slang::String& fileName, const Slang::String& text)
- {
- RefPtr<FileStream> stream = new FileStream;
- SLANG_RETURN_ON_FAIL(stream->init(fileName, FileMode::Create));
+ size_t readSizeInBytes;
+ SLANG_RETURN_ON_FAIL(stream.read(data, sizeInBytes, readSizeInBytes));
- StreamWriter writer;
- SLANG_RETURN_ON_FAIL(writer.init(stream));
- SLANG_RETURN_ON_FAIL(writer.write(text));
+ // If not all read just return an error
+ return (sizeInBytes == readSizeInBytes) ? SLANG_OK : SLANG_FAIL;
+}
- return SLANG_OK;
- }
+SlangResult File::writeAllBytes(const String& path, const void* data, size_t size)
+{
+ FileStream stream;
+ SLANG_RETURN_ON_FAIL(
+ stream.init(path, FileMode::Create, FileAccess::Write, FileShare::ReadWrite));
+ SLANG_RETURN_ON_FAIL(stream.write(data, size));
+ return SLANG_OK;
+}
+
+SlangResult File::writeAllText(const Slang::String& fileName, const Slang::String& text)
+{
+ RefPtr<FileStream> stream = new FileStream;
+ SLANG_RETURN_ON_FAIL(stream->init(fileName, FileMode::Create));
- SlangResult File::writeAllTextIfChanged(const String& fileName, UnownedStringSlice text)
+ StreamWriter writer;
+ SLANG_RETURN_ON_FAIL(writer.init(stream));
+ SLANG_RETURN_ON_FAIL(writer.write(text));
+
+ return SLANG_OK;
+}
+
+SlangResult File::writeAllTextIfChanged(const String& fileName, UnownedStringSlice text)
+{
+ String existingContent;
+ auto result = File::readAllText(fileName, existingContent);
+ if (SLANG_FAILED(result) || existingContent != text)
{
- String existingContent;
- auto result = File::readAllText(fileName, existingContent);
- if (SLANG_FAILED(result) || existingContent != text)
- {
- return File::writeNativeText(fileName, text.begin(), text.getLength());
- }
- return SLANG_OK;
+ return File::writeNativeText(fileName, text.begin(), text.getLength());
}
+ return SLANG_OK;
+}
- /* static */SlangResult File::writeNativeText(const String& path, const void* data, size_t size)
+/* static */ SlangResult File::writeNativeText(const String& path, const void* data, size_t size)
+{
+ FILE* file = fopen(path.getBuffer(), "w");
+ if (!file)
{
- FILE* file = fopen(path.getBuffer(), "w");
- if (!file)
- {
- return SLANG_FAIL;
- }
+ return SLANG_FAIL;
+ }
- const auto count = fwrite(data, size, 1, file);
- fclose(file);
+ const auto count = fwrite(data, size, 1, file);
+ fclose(file);
- return (count == 1) ? SLANG_OK : SLANG_FAIL;
- }
+ return (count == 1) ? SLANG_OK : SLANG_FAIL;
+}
- String URI::getPath() const
- {
- Index startIndex = uri.indexOf("://");
- if (startIndex == -1)
- return String();
- startIndex += 3;
- Index endIndex = uri.indexOf('?');
- if (endIndex == -1)
- endIndex = uri.getLength();
- StringBuilder sb;
+String URI::getPath() const
+{
+ Index startIndex = uri.indexOf("://");
+ if (startIndex == -1)
+ return String();
+ startIndex += 3;
+ Index endIndex = uri.indexOf('?');
+ if (endIndex == -1)
+ endIndex = uri.getLength();
+ StringBuilder sb;
#if SLANG_WINDOWS_FAMILY
- if (uri[startIndex] == '/')
- startIndex++;
+ if (uri[startIndex] == '/')
+ startIndex++;
#endif
- for (Index i = startIndex; i < endIndex;)
+ for (Index i = startIndex; i < endIndex;)
+ {
+ auto ch = uri[i];
+ if (ch == '%')
{
- auto ch = uri[i];
- if (ch == '%')
- {
- Int charVal = CharUtil::getHexDigitValue(uri[i + 1]) * 16 +
- CharUtil::getHexDigitValue(uri[i + 2]);
- sb.appendChar((char)charVal);
- i += 3;
- }
- else
- {
- sb.appendChar(uri[i]);
- i++;
- }
+ Int charVal = CharUtil::getHexDigitValue(uri[i + 1]) * 16 +
+ CharUtil::getHexDigitValue(uri[i + 2]);
+ sb.appendChar((char)charVal);
+ i += 3;
+ }
+ else
+ {
+ sb.appendChar(uri[i]);
+ i++;
}
- return sb.produceString();
}
+ return sb.produceString();
+}
- StringSlice URI::getProtocol() const
- {
- Index separatorIndex = uri.indexOf("://");
- if (separatorIndex != -1)
- return uri.subString(0, separatorIndex);
- return StringSlice();
- }
+StringSlice URI::getProtocol() const
+{
+ Index separatorIndex = uri.indexOf("://");
+ if (separatorIndex != -1)
+ return uri.subString(0, separatorIndex);
+ return StringSlice();
+}
- bool URI::isSafeURIChar(char ch)
- {
- return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
- ch == '-' || ch == '_' || ch == '/' || ch == '.';
- }
+bool URI::isSafeURIChar(char ch)
+{
+ return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
+ ch == '-' || ch == '_' || ch == '/' || ch == '.';
+}
- URI URI::fromLocalFilePath(UnownedStringSlice path)
- {
- URI uri;
- StringBuilder sb;
- sb << "file://";
+URI URI::fromLocalFilePath(UnownedStringSlice path)
+{
+ URI uri;
+ StringBuilder sb;
+ sb << "file://";
#if SLANG_WINDOWS_FAMILY
- sb << "/";
+ sb << "/";
#endif
- for (auto ch : path)
+ for (auto ch : path)
+ {
+ if (isSafeURIChar(ch))
{
- if (isSafeURIChar(ch))
- {
- sb.appendChar(ch);
- }
- else if (ch == '\\')
- {
- sb.appendChar('/');
- }
- else
- {
- char buffer[32];
- int length = intToAscii(buffer, (int)ch, 16);
- sb << "%" << UnownedStringSlice(buffer, length);
- }
+ sb.appendChar(ch);
+ }
+ else if (ch == '\\')
+ {
+ sb.appendChar('/');
+ }
+ else
+ {
+ char buffer[32];
+ int length = intToAscii(buffer, (int)ch, 16);
+ sb << "%" << UnownedStringSlice(buffer, length);
}
- return URI::fromString(sb.getUnownedSlice());
}
+ return URI::fromString(sb.getUnownedSlice());
+}
- URI URI::fromString(UnownedStringSlice uriString)
- {
- URI uri;
- uri.uri = uriString;
- return uri;
- }
+URI URI::fromString(UnownedStringSlice uriString)
+{
+ URI uri;
+ uri.uri = uriString;
+ return uri;
+}
- SlangResult LockFile::open(const String& fileName)
- {
+SlangResult LockFile::open(const String& fileName)
+{
#if SLANG_WINDOWS_FAMILY
- m_fileHandle = ::CreateFileW(
- fileName.toWString(),
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
- NULL
- );
- m_isOpen = m_fileHandle != INVALID_HANDLE_VALUE;
+ m_fileHandle = ::CreateFileW(
+ fileName.toWString(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+ NULL);
+ m_isOpen = m_fileHandle != INVALID_HANDLE_VALUE;
#else
- m_fileHandle = ::open(fileName.getBuffer(), O_RDWR | O_CREAT, 0600);
- m_isOpen = m_fileHandle != -1;
+ m_fileHandle = ::open(fileName.getBuffer(), O_RDWR | O_CREAT, 0600);
+ m_isOpen = m_fileHandle != -1;
#endif
- return m_isOpen ? SLANG_OK : SLANG_E_CANNOT_OPEN;
- }
+ return m_isOpen ? SLANG_OK : SLANG_E_CANNOT_OPEN;
+}
- void LockFile::close()
- {
- if (!m_isOpen)
- return;
+void LockFile::close()
+{
+ if (!m_isOpen)
+ return;
#if SLANG_WINDOWS_FAMILY
- ::CloseHandle(m_fileHandle);
+ ::CloseHandle(m_fileHandle);
#else
- ::close(m_fileHandle);
+ ::close(m_fileHandle);
#endif
- m_isOpen = false;
- }
+ m_isOpen = false;
+}
- SlangResult LockFile::tryLock(LockType lockType)
- {
- if (!m_isOpen)
- return SLANG_E_CANNOT_OPEN;
+SlangResult LockFile::tryLock(LockType lockType)
+{
+ if (!m_isOpen)
+ return SLANG_E_CANNOT_OPEN;
- SlangResult result = SLANG_OK;
+ SlangResult result = SLANG_OK;
#if SLANG_WINDOWS_FAMILY
- OVERLAPPED overlapped = {0};
- DWORD flags = lockType == LockType::Shared ? LOCKFILE_FAIL_IMMEDIATELY : (LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY);
- if (::LockFileEx(m_fileHandle, flags, DWORD(0), ~DWORD(0), ~DWORD(0), &overlapped) == 0)
- {
- result = SLANG_E_TIME_OUT;
- }
+ OVERLAPPED overlapped = {0};
+ DWORD flags = lockType == LockType::Shared
+ ? LOCKFILE_FAIL_IMMEDIATELY
+ : (LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY);
+ if (::LockFileEx(m_fileHandle, flags, DWORD(0), ~DWORD(0), ~DWORD(0), &overlapped) == 0)
+ {
+ result = SLANG_E_TIME_OUT;
+ }
#else
- int operation = lockType == LockType::Shared ? (LOCK_SH | LOCK_NB) : (LOCK_EX | LOCK_NB);
- if (::flock(m_fileHandle, operation) != 0)
- {
- result = SLANG_E_TIME_OUT;
- }
-#endif
- return result;
+ int operation = lockType == LockType::Shared ? (LOCK_SH | LOCK_NB) : (LOCK_EX | LOCK_NB);
+ if (::flock(m_fileHandle, operation) != 0)
+ {
+ result = SLANG_E_TIME_OUT;
}
+#endif
+ return result;
+}
- SlangResult LockFile::lock(LockType lockType)
- {
- if (!m_isOpen)
- return SLANG_E_CANNOT_OPEN;
+SlangResult LockFile::lock(LockType lockType)
+{
+ if (!m_isOpen)
+ return SLANG_E_CANNOT_OPEN;
- SlangResult result = SLANG_OK;
+ SlangResult result = SLANG_OK;
#if SLANG_WINDOWS_FAMILY
- OVERLAPPED overlapped = {0};
- overlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- DWORD flags = lockType == LockType::Shared ? 0 : LOCKFILE_EXCLUSIVE_LOCK;
- if (::LockFileEx(m_fileHandle, flags, DWORD(0), ~DWORD(0), ~DWORD(0), &overlapped) == 0)
+ OVERLAPPED overlapped = {0};
+ overlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ DWORD flags = lockType == LockType::Shared ? 0 : LOCKFILE_EXCLUSIVE_LOCK;
+ if (::LockFileEx(m_fileHandle, flags, DWORD(0), ~DWORD(0), ~DWORD(0), &overlapped) == 0)
+ {
+ auto err = ::GetLastError();
+ if (err == ERROR_IO_PENDING)
{
- auto err = ::GetLastError();
- if (err == ERROR_IO_PENDING)
- {
- DWORD bytes;
- if (::GetOverlappedResult(m_fileHandle, &overlapped, &bytes, TRUE) == 0)
- {
- result = SLANG_E_INTERNAL_FAIL;
- }
- }
- else
+ DWORD bytes;
+ if (::GetOverlappedResult(m_fileHandle, &overlapped, &bytes, TRUE) == 0)
{
result = SLANG_E_INTERNAL_FAIL;
}
}
- ::CloseHandle(overlapped.hEvent);
-#else
- int operation = lockType == LockType::Shared ? LOCK_SH : LOCK_EX;
- if (::flock(m_fileHandle, operation) != 0)
+ else
{
result = SLANG_E_INTERNAL_FAIL;
}
+ }
+ ::CloseHandle(overlapped.hEvent);
+#else
+ int operation = lockType == LockType::Shared ? LOCK_SH : LOCK_EX;
+ if (::flock(m_fileHandle, operation) != 0)
+ {
+ result = SLANG_E_INTERNAL_FAIL;
+ }
#endif
- return result;
+ return result;
}
- SlangResult LockFile::unlock()
- {
- if (!m_isOpen)
- return SLANG_E_CANNOT_OPEN;
+SlangResult LockFile::unlock()
+{
+ if (!m_isOpen)
+ return SLANG_E_CANNOT_OPEN;
#if SLANG_WINDOWS_FAMILY
- OVERLAPPED overlapped = {0};
- if (::UnlockFileEx(m_fileHandle, DWORD(0), ~DWORD(0), ~DWORD(0), &overlapped) == 0)
- {
- return SLANG_E_INTERNAL_FAIL;
- }
+ OVERLAPPED overlapped = {0};
+ if (::UnlockFileEx(m_fileHandle, DWORD(0), ~DWORD(0), ~DWORD(0), &overlapped) == 0)
+ {
+ return SLANG_E_INTERNAL_FAIL;
+ }
#else
- if (::flock(m_fileHandle, LOCK_UN) != 0)
- {
- return SLANG_E_INTERNAL_FAIL;
- }
+ if (::flock(m_fileHandle, LOCK_UN) != 0)
+ {
+ return SLANG_E_INTERNAL_FAIL;
+ }
#endif
- return SLANG_OK;
+ return SLANG_OK;
}
- LockFile::LockFile()
- : m_isOpen(false)
- {}
+LockFile::LockFile()
+ : m_isOpen(false)
+{
+}
- LockFile::~LockFile()
- {
- close();
- }
+LockFile::~LockFile()
+{
+ close();
}
+} // namespace Slang
diff --git a/source/core/slang-io.h b/source/core/slang-io.h
index 676635a36..73dfd31d7 100644
--- a/source/core/slang-io.h
+++ b/source/core/slang-io.h
@@ -1,326 +1,350 @@
#ifndef SLANG_CORE_IO_H
#define SLANG_CORE_IO_H
-#include "slang-string.h"
+#include "slang-blob.h"
+#include "slang-secure-crt.h"
#include "slang-stream.h"
+#include "slang-string.h"
#include "slang-text-io.h"
-#include "slang-secure-crt.h"
-#include "slang-blob.h"
namespace Slang
{
- class File
- {
- public:
- static bool exists(const String& fileName);
+class File
+{
+public:
+ static bool exists(const String& fileName);
- static SlangResult readAllText(const String& fileName, String& outString);
+ static SlangResult readAllText(const String& fileName, String& outString);
- static SlangResult readAllBytes(const String& fileName, List<unsigned char>& out);
- static SlangResult readAllBytes(const String& fileName, ScopedAllocation& out);
+ static SlangResult readAllBytes(const String& fileName, List<unsigned char>& out);
+ static SlangResult readAllBytes(const String& fileName, ScopedAllocation& out);
- static SlangResult writeAllText(const String& fileName, const String& text);
+ static SlangResult writeAllText(const String& fileName, const String& text);
- static SlangResult writeAllTextIfChanged(const String& fileName, UnownedStringSlice text);
+ static SlangResult writeAllTextIfChanged(const String& fileName, UnownedStringSlice text);
- /// Write as text in native form for the target (so typically may change line endings )
- static SlangResult writeNativeText(const String& filename, const void* data, size_t size);
+ /// Write as text in native form for the target (so typically may change line endings )
+ static SlangResult writeNativeText(const String& filename, const void* data, size_t size);
- static SlangResult writeAllBytes(const String& fileName, const void* data, size_t size);
+ static SlangResult writeAllBytes(const String& fileName, const void* data, size_t size);
- static SlangResult remove(const String& fileName);
+ static SlangResult remove(const String& fileName);
- static SlangResult makeExecutable(const String& fileName);
+ static SlangResult makeExecutable(const String& fileName);
- /// Creates a temporary file typically in some way based on the prefix
- /// The file will be *created* with the outFileName, on success.
- /// It's creation in necessary to lock that particular name.
- static SlangResult generateTemporary(const UnownedStringSlice& prefix, String& outFileName);
- };
+ /// Creates a temporary file typically in some way based on the prefix
+ /// The file will be *created* with the outFileName, on success.
+ /// It's creation in necessary to lock that particular name.
+ static SlangResult generateTemporary(const UnownedStringSlice& prefix, String& outFileName);
+};
- class Path
- {
- public:
- typedef uint32_t SimplifyIntegral;
+class Path
+{
+public:
+ typedef uint32_t SimplifyIntegral;
- struct SimplifyFlag
+ struct SimplifyFlag
+ {
+ enum Enum : SimplifyIntegral
{
- enum Enum : SimplifyIntegral
- {
- /// Can only simplify to an absolute path. Will return an error if not possible.
- /// Useful to constrain a path, such as when wanting something like 'chroot'.
- AbsoluteOnly = 0x1,
- /// If the simplified path is a root path, remove the root.
- /// Will mean that for example
- /// "/" -> "."
- /// "/a/.." -> "."
- /// "/a" -> "a"
- /// Its worth noting that a path prefixed "/" will never be returned and if *just* the root it specified
- /// it will return as ".".
- NoRoot = 0x2,
- };
+ /// Can only simplify to an absolute path. Will return an error if not possible.
+ /// Useful to constrain a path, such as when wanting something like 'chroot'.
+ AbsoluteOnly = 0x1,
+ /// If the simplified path is a root path, remove the root.
+ /// Will mean that for example
+ /// "/" -> "."
+ /// "/a/.." -> "."
+ /// "/a" -> "a"
+ /// Its worth noting that a path prefixed "/" will never be returned and if *just* the
+ /// root it specified it will return as ".".
+ NoRoot = 0x2,
};
+ };
- // A more convenient typesafe way to specify the SimplifyFlag combinations
- enum SimplifyStyle : SimplifyIntegral
- {
- Normal = 0,
- AbsoluteOnly = SimplifyFlag::AbsoluteOnly,
- NoRoot = SimplifyFlag::NoRoot,
- AbsoluteOnlyAndNoRoot = SimplifyFlag::AbsoluteOnly | SimplifyFlag::NoRoot,
- };
+ // A more convenient typesafe way to specify the SimplifyFlag combinations
+ enum SimplifyStyle : SimplifyIntegral
+ {
+ Normal = 0,
+ AbsoluteOnly = SimplifyFlag::AbsoluteOnly,
+ NoRoot = SimplifyFlag::NoRoot,
+ AbsoluteOnlyAndNoRoot = SimplifyFlag::AbsoluteOnly | SimplifyFlag::NoRoot,
+ };
- enum class Type
- {
- Unknown,
- File,
- Directory,
- };
+ enum class Type
+ {
+ Unknown,
+ File,
+ Directory,
+ };
- typedef uint32_t TypeFlags;
- struct TypeFlag
+ typedef uint32_t TypeFlags;
+ struct TypeFlag
+ {
+ enum Enum : TypeFlags
{
- enum Enum : TypeFlags
- {
- Unknown = TypeFlags(1) << int(Type::Unknown),
- File = TypeFlags(1) << int(Type::File),
- Directory = TypeFlags(1) << int(Type::Directory),
- };
+ Unknown = TypeFlags(1) << int(Type::Unknown),
+ File = TypeFlags(1) << int(Type::File),
+ Directory = TypeFlags(1) << int(Type::Directory),
};
+ };
- class Visitor
- {
- public:
- virtual void accept(Type type, const UnownedStringSlice& filename) = 0;
- };
+ class Visitor
+ {
+ public:
+ virtual void accept(Type type, const UnownedStringSlice& filename) = 0;
+ };
- static const char kPathDelimiter = '/';
+ static const char kPathDelimiter = '/';
#if SLANG_WINDOWS_FAMILY
- static const char kOSCanonicalPathDelimiter = '\\';
- static const char kOSAlternativePathDelimiter = '/';
+ static const char kOSCanonicalPathDelimiter = '\\';
+ static const char kOSAlternativePathDelimiter = '/';
#else
- static const char kOSCanonicalPathDelimiter = '/';
- static const char kOSAlternativePathDelimiter = '/';
+ static const char kOSCanonicalPathDelimiter = '/';
+ static const char kOSAlternativePathDelimiter = '/';
#endif
- /// Finds all all the items in the specified directory, that matches the pattern.
- ///
- /// @param directoryPath The directory to do the search in. If the directory is not found, SLANG_E_NOT_FOUND is returned
- /// @param pattern. The pattern to match against. The pattern matching is targtet specific (ie window matching is different to linux/unix). Passing nullptr means no matching.
- /// @return is SLANG_E_NOT_FOUND if the directoryPath is not found
- static SlangResult find(const String& directoryPath, const char* pattern, Visitor* visitor);
-
- /// Returns -1 if no separator is found
- static Index findLastSeparatorIndex(String const& path) { return findLastSeparatorIndex(path.getUnownedSlice()); }
- static Index findLastSeparatorIndex(UnownedStringSlice const& path);
- /// Finds the index of the last dot in a path, else returns -1
- static Index findExtIndex(String const& path) { return findExtIndex(path.getUnownedSlice()); }
- static Index findExtIndex(UnownedStringSlice const& path);
-
- /// True if isn't just a name (ie has any path separator)
- /// Note this is no the same as having a 'parent' as '/thing' 'has a path', but it doesn't have a parent.
- static bool hasPath(const UnownedStringSlice& path) { return findLastSeparatorIndex(path) >= 0; }
- static bool hasPath(const String& path) { return findLastSeparatorIndex(path) >= 0; }
-
- static String replaceExt(const String& path, const char* newExt);
- static String getFileName(const String& path);
- static String getPathWithoutExt(const String& path);
-
- static String getPathExt(const String& path) { return getPathExt(path.getUnownedSlice()); }
- static UnownedStringSlice getPathExt(const UnownedStringSlice& path);
-
- static String getParentDirectory(const String& path);
-
- static String getFileNameWithoutExt(const String& path);
-
- static String combine(const String& path1, const String& path2);
- static String combine(const String& path1, const String& path2, const String& path3);
-
- /// Combine path sections and store the result in outBuilder
- static void combineIntoBuilder(const UnownedStringSlice& path1, const UnownedStringSlice& path2, StringBuilder& outBuilder);
-
- /// Append a path, taking into account path separators onto the end of ioBuilder
- static void append(StringBuilder& ioBuilder, const UnownedStringSlice& path);
-
- static bool createDirectory(const String& path);
- static bool createDirectoryRecursive(const String& path);
-
- /// Accept either style of delimiter
- SLANG_FORCE_INLINE static bool isDelimiter(char c) { return c == '/' || c == '\\'; }
-
- /// True if the element appears to be a drive specification (where element is the prefix to a path that isn't a directory)
- /// @param pathPrefix The path prefix to test if it's a drive specification
- static bool isDriveSpecification(const UnownedStringSlice& pathPrefix);
-
- /// Splits the path into it's individual bits
- /// Absolute paths of the form "/" will become [""]
- /// Absolute paths of the form "a:/" will become ["a:", ""]
- /// A drive specification of the form "a:" will become ["a:"]
- /// Relative paths that are in effect "." will become []
- static void split(const UnownedStringSlice& path, List<UnownedStringSlice>& splitOut);
-
- /// Strips .. and . as much as it can
- static String simplify(const UnownedStringSlice& path);
- static String simplify(const String& path) { return simplify(path.getUnownedSlice()); }
-
- /// Given a path simplifies it such the the resultant path is absolute (ie contains no . or ..)
- /// Same behavior as simplify around the root
- static SlangResult simplify(const UnownedStringSlice& path, SimplifyStyle style, StringBuilder& outPath);
- static SlangResult simplify(const String& path, SimplifyStyle style, StringBuilder& outPath) { return simplify(path.getUnownedSlice(), style, outPath); }
- static SlangResult simplify(const char* path, SimplifyStyle style, StringBuilder& outPath) { return simplify(UnownedStringSlice(path), style, outPath); }
-
- /// Simplifies the path split up
- static void simplify(List<UnownedStringSlice>& ioSplit);
-
- /// Join the parts of the path to produce an output path
- static void join(const UnownedStringSlice* slices, Index count, StringBuilder& out);
-
- /// Returns true if the path is absolute
- static bool isAbsolute(const UnownedStringSlice& path);
- static bool isAbsolute(const String& path) { return isAbsolute(path.getUnownedSlice()); }
-
- /// Returns true if path contains contains an element of . or ..
- static bool hasRelativeElement(const UnownedStringSlice& path);
- static bool hasRelativeElement(const String& path) { return hasRelativeElement(path.getUnownedSlice()); }
-
- /// Determines the type of file at the path
- /// @param path The path to test
- /// @param outPathType Holds the object type at the path on success
- /// @return SLANG_OK on success
- static SlangResult getPathType(const String& path, SlangPathType* outPathType);
-
- /// Determines the canonical equivalent path to path.
- /// The path returned should reference the identical object - and two different references to the same path should return the same canonical path
- /// @param path Path to get the canonical path for
- /// @param outCanonicalPath The canonical path for 'path' is call is successful
- /// @return SLANG_OK on success
- static SlangResult getCanonical(const String& path, String& outCanonicalPath);
-
- /// Returns the current working directory
- /// @return The path in platform native format. Returns empty string if failed.
- static String getCurrentPath();
-
- /// Returns the executable path
- /// @return The path in platform native format. Returns empty string if failed.
- static String getExecutablePath();
-
- /// Returns the first element of the path or an empty slice if there is none
- /// This broadly equivalent to returning the first element of split
- /// @param path Path to extract first element from
- /// @return The first element of the path, or empty
- static UnownedStringSlice getFirstElement(const UnownedStringSlice& path);
-
- /// Remove a file or directory at specified path. The directory must be empty for it to be removed
- /// @param path
- /// @return SLANG_OK if file or directory is removed
- static SlangResult remove(const String& path);
+ /// Finds all all the items in the specified directory, that matches the pattern.
+ ///
+ /// @param directoryPath The directory to do the search in. If the directory is not found,
+ /// SLANG_E_NOT_FOUND is returned
+ /// @param pattern. The pattern to match against. The pattern matching is targtet specific (ie
+ /// window matching is different to linux/unix). Passing nullptr means no matching.
+ /// @return is SLANG_E_NOT_FOUND if the directoryPath is not found
+ static SlangResult find(const String& directoryPath, const char* pattern, Visitor* visitor);
+
+ /// Returns -1 if no separator is found
+ static Index findLastSeparatorIndex(String const& path)
+ {
+ return findLastSeparatorIndex(path.getUnownedSlice());
+ }
+ static Index findLastSeparatorIndex(UnownedStringSlice const& path);
+ /// Finds the index of the last dot in a path, else returns -1
+ static Index findExtIndex(String const& path) { return findExtIndex(path.getUnownedSlice()); }
+ static Index findExtIndex(UnownedStringSlice const& path);
+
+ /// True if isn't just a name (ie has any path separator)
+ /// Note this is no the same as having a 'parent' as '/thing' 'has a path', but it doesn't have
+ /// a parent.
+ static bool hasPath(const UnownedStringSlice& path)
+ {
+ return findLastSeparatorIndex(path) >= 0;
+ }
+ static bool hasPath(const String& path) { return findLastSeparatorIndex(path) >= 0; }
+
+ static String replaceExt(const String& path, const char* newExt);
+ static String getFileName(const String& path);
+ static String getPathWithoutExt(const String& path);
+
+ static String getPathExt(const String& path) { return getPathExt(path.getUnownedSlice()); }
+ static UnownedStringSlice getPathExt(const UnownedStringSlice& path);
+
+ static String getParentDirectory(const String& path);
+
+ static String getFileNameWithoutExt(const String& path);
+
+ static String combine(const String& path1, const String& path2);
+ static String combine(const String& path1, const String& path2, const String& path3);
+
+ /// Combine path sections and store the result in outBuilder
+ static void combineIntoBuilder(
+ const UnownedStringSlice& path1,
+ const UnownedStringSlice& path2,
+ StringBuilder& outBuilder);
+
+ /// Append a path, taking into account path separators onto the end of ioBuilder
+ static void append(StringBuilder& ioBuilder, const UnownedStringSlice& path);
+
+ static bool createDirectory(const String& path);
+ static bool createDirectoryRecursive(const String& path);
+
+ /// Accept either style of delimiter
+ SLANG_FORCE_INLINE static bool isDelimiter(char c) { return c == '/' || c == '\\'; }
+
+ /// True if the element appears to be a drive specification (where element is the prefix to a
+ /// path that isn't a directory)
+ /// @param pathPrefix The path prefix to test if it's a drive specification
+ static bool isDriveSpecification(const UnownedStringSlice& pathPrefix);
+
+ /// Splits the path into it's individual bits
+ /// Absolute paths of the form "/" will become [""]
+ /// Absolute paths of the form "a:/" will become ["a:", ""]
+ /// A drive specification of the form "a:" will become ["a:"]
+ /// Relative paths that are in effect "." will become []
+ static void split(const UnownedStringSlice& path, List<UnownedStringSlice>& splitOut);
+
+ /// Strips .. and . as much as it can
+ static String simplify(const UnownedStringSlice& path);
+ static String simplify(const String& path) { return simplify(path.getUnownedSlice()); }
+
+ /// Given a path simplifies it such the the resultant path is absolute (ie contains no . or ..)
+ /// Same behavior as simplify around the root
+ static SlangResult simplify(
+ const UnownedStringSlice& path,
+ SimplifyStyle style,
+ StringBuilder& outPath);
+ static SlangResult simplify(const String& path, SimplifyStyle style, StringBuilder& outPath)
+ {
+ return simplify(path.getUnownedSlice(), style, outPath);
+ }
+ static SlangResult simplify(const char* path, SimplifyStyle style, StringBuilder& outPath)
+ {
+ return simplify(UnownedStringSlice(path), style, outPath);
+ }
- /// Remove a file or directory at specified path. The directory can be non-empty.
- /// @param path
- /// @return SLANG_OK if file or directory is removed
- static SlangResult removeNonEmpty(const String& path);
+ /// Simplifies the path split up
+ static void simplify(List<UnownedStringSlice>& ioSplit);
- static bool equals(String path1, String path2);
+ /// Join the parts of the path to produce an output path
+ static void join(const UnownedStringSlice* slices, Index count, StringBuilder& out);
- /// Turn `path` into a relative path from base.
- static String getRelativePath(String base, String path);
- };
+ /// Returns true if the path is absolute
+ static bool isAbsolute(const UnownedStringSlice& path);
+ static bool isAbsolute(const String& path) { return isAbsolute(path.getUnownedSlice()); }
- struct URI
+ /// Returns true if path contains contains an element of . or ..
+ static bool hasRelativeElement(const UnownedStringSlice& path);
+ static bool hasRelativeElement(const String& path)
{
- String uri;
- bool operator==(const URI& other) const { return uri == other.uri; }
- bool operator!=(const URI& other) const { return uri != other.uri; }
+ return hasRelativeElement(path.getUnownedSlice());
+ }
+
+ /// Determines the type of file at the path
+ /// @param path The path to test
+ /// @param outPathType Holds the object type at the path on success
+ /// @return SLANG_OK on success
+ static SlangResult getPathType(const String& path, SlangPathType* outPathType);
+
+ /// Determines the canonical equivalent path to path.
+ /// The path returned should reference the identical object - and two different references to
+ /// the same path should return the same canonical path
+ /// @param path Path to get the canonical path for
+ /// @param outCanonicalPath The canonical path for 'path' is call is successful
+ /// @return SLANG_OK on success
+ static SlangResult getCanonical(const String& path, String& outCanonicalPath);
+
+ /// Returns the current working directory
+ /// @return The path in platform native format. Returns empty string if failed.
+ static String getCurrentPath();
+
+ /// Returns the executable path
+ /// @return The path in platform native format. Returns empty string if failed.
+ static String getExecutablePath();
+
+ /// Returns the first element of the path or an empty slice if there is none
+ /// This broadly equivalent to returning the first element of split
+ /// @param path Path to extract first element from
+ /// @return The first element of the path, or empty
+ static UnownedStringSlice getFirstElement(const UnownedStringSlice& path);
+
+ /// Remove a file or directory at specified path. The directory must be empty for it to be
+ /// removed
+ /// @param path
+ /// @return SLANG_OK if file or directory is removed
+ static SlangResult remove(const String& path);
+
+ /// Remove a file or directory at specified path. The directory can be non-empty.
+ /// @param path
+ /// @return SLANG_OK if file or directory is removed
+ static SlangResult removeNonEmpty(const String& path);
+
+ static bool equals(String path1, String path2);
+
+ /// Turn `path` into a relative path from base.
+ static String getRelativePath(String base, String path);
+};
+
+struct URI
+{
+ String uri;
+ bool operator==(const URI& other) const { return uri == other.uri; }
+ bool operator!=(const URI& other) const { return uri != other.uri; }
- HashCode getHashCode() const { return uri.getHashCode(); }
+ HashCode getHashCode() const { return uri.getHashCode(); }
- bool isLocalFile() { return uri.startsWith("file://"); };
- String getPath() const;
- StringSlice getProtocol() const;
+ bool isLocalFile() { return uri.startsWith("file://"); };
+ String getPath() const;
+ StringSlice getProtocol() const;
- static URI fromLocalFilePath(UnownedStringSlice path);
- static URI fromString(UnownedStringSlice uriString);
- static bool isSafeURIChar(char ch);
- };
+ static URI fromLocalFilePath(UnownedStringSlice path);
+ static URI fromString(UnownedStringSlice uriString);
+ static bool isSafeURIChar(char ch);
+};
- /// Helper class abstracting lock files.
- /// Uses LockFileEx() on windows systems and flock() on POSIX systems.
- class LockFile
+/// Helper class abstracting lock files.
+/// Uses LockFileEx() on windows systems and flock() on POSIX systems.
+class LockFile
+{
+public:
+ enum class LockType
{
- public:
- enum class LockType
- {
- Exclusive,
- Shared,
- };
+ Exclusive,
+ Shared,
+ };
- /// Open the lock file. This will create the file if it doesn't exist yet.
- /// @param fileName File name to open.
- /// @return SLANG_OK on success.
- SlangResult open(const String& fileName);
+ /// Open the lock file. This will create the file if it doesn't exist yet.
+ /// @param fileName File name to open.
+ /// @return SLANG_OK on success.
+ SlangResult open(const String& fileName);
- /// Closes the lock file.
- void close();
+ /// Closes the lock file.
+ void close();
- /// Returns true if the lock file is open.
- bool isOpen() const { return m_isOpen; }
+ /// Returns true if the lock file is open.
+ bool isOpen() const { return m_isOpen; }
- /// Acquire the lock in non-blocking mode.
- /// @param lockType Lock type (Exclusive or Shared).
- /// @return SLANG_OK on success. SLANG_E_TIME_OUT if the lock is already held.
- SlangResult tryLock(LockType lockType = LockType::Exclusive);
+ /// Acquire the lock in non-blocking mode.
+ /// @param lockType Lock type (Exclusive or Shared).
+ /// @return SLANG_OK on success. SLANG_E_TIME_OUT if the lock is already held.
+ SlangResult tryLock(LockType lockType = LockType::Exclusive);
- /// Acquire the lock in blocking mode.
- /// @param lockType Lock type (Exclusive or Shared).
- /// @return SLANG_OK on success.
- SlangResult lock(LockType lockType = LockType::Exclusive);
+ /// Acquire the lock in blocking mode.
+ /// @param lockType Lock type (Exclusive or Shared).
+ /// @return SLANG_OK on success.
+ SlangResult lock(LockType lockType = LockType::Exclusive);
- /// Release the lock.
- /// @return SLANG_OK on success.
- SlangResult unlock();
+ /// Release the lock.
+ /// @return SLANG_OK on success.
+ SlangResult unlock();
- LockFile();
- ~LockFile();
+ LockFile();
+ ~LockFile();
- private:
- LockFile(const LockFile&) = delete;
- LockFile(LockFile&&) = delete;
- LockFile& operator=(const LockFile&) = delete;
- LockFile& operator=(LockFile&&) = delete;
+private:
+ LockFile(const LockFile&) = delete;
+ LockFile(LockFile&&) = delete;
+ LockFile& operator=(const LockFile&) = delete;
+ LockFile& operator=(LockFile&&) = delete;
#if SLANG_WINDOWS_FAMILY
- void* m_fileHandle;
+ void* m_fileHandle;
#else
- int m_fileHandle;
+ int m_fileHandle;
#endif
- bool m_isOpen;
- };
+ bool m_isOpen;
+};
- class LockFileGuard
+class LockFileGuard
+{
+public:
+ LockFileGuard(LockFile& lockFile, LockFile::LockType lockType = LockFile::LockType::Exclusive)
+ : m_lockFile(lockFile)
{
- public:
- LockFileGuard(LockFile& lockFile, LockFile::LockType lockType = LockFile::LockType::Exclusive)
- : m_lockFile(lockFile)
- {
- m_lockFile.lock(lockType);
- }
+ m_lockFile.lock(lockType);
+ }
- ~LockFileGuard()
- {
- m_lockFile.unlock();
- }
+ ~LockFileGuard() { m_lockFile.unlock(); }
- private:
- LockFileGuard(const LockFileGuard&) = delete;
- LockFileGuard(LockFileGuard&&) = delete;
- LockFileGuard& operator=(const LockFileGuard&) = delete;
- LockFileGuard& operator=(LockFileGuard&&) = delete;
+private:
+ LockFileGuard(const LockFileGuard&) = delete;
+ LockFileGuard(LockFileGuard&&) = delete;
+ LockFileGuard& operator=(const LockFileGuard&) = delete;
+ LockFileGuard& operator=(LockFileGuard&&) = delete;
- LockFile& m_lockFile;
- };
+ LockFile& m_lockFile;
+};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-linked-list.h b/source/core/slang-linked-list.h
index ff8f7ce40..a8ebdf1b2 100644
--- a/source/core/slang-linked-list.h
+++ b/source/core/slang-linked-list.h
@@ -1,21 +1,22 @@
#ifndef SLANG_CORE_LINKED_LIST_H
#define SLANG_CORE_LINKED_LIST_H
-#include "slang.h"
-
#include "slang-allocator.h"
#include "slang-list.h"
+#include "slang.h"
+
#include <type_traits>
namespace Slang
{
-template <typename T>
+template<typename T>
class LinkedList;
-template <typename T>
+template<typename T>
class LinkedNode
{
- template <typename T1> friend class LinkedList;
+ template<typename T1>
+ friend class LinkedList;
private:
LinkedNode<T>* prev = nullptr;
@@ -25,9 +26,7 @@ private:
public:
T value;
LinkedNode(LinkedList<T>* lnk)
- : list(lnk)
- {
- };
+ : list(lnk){};
LinkedNode<T>* getPrevious() { return prev; };
LinkedNode<T>* getNext() { return next; };
const LinkedNode<T>* getNext() const { return next; };
@@ -82,12 +81,14 @@ public:
}
};
-template <typename T> class LinkedList
+template<typename T>
+class LinkedList
{
- template <typename T1> friend class LinkedNode;
+ template<typename T1>
+ friend class LinkedNode;
private:
- LinkedNode<T>* head, *tail;
+ LinkedNode<T>*head, *tail;
int count;
public:
@@ -96,7 +97,7 @@ public:
{
public:
using Node = std::conditional_t<Const, const LinkedNode<T>, LinkedNode<T>>;
- Node* current, *next;
+ Node *current, *next;
void setCurrent(Node* cur)
{
current = cur;
@@ -107,8 +108,7 @@ public:
}
GenIterator() { current = next = nullptr; }
GenIterator(Node* cur) { setCurrent(cur); }
- std::conditional_t<Const, const T&, T&>
- operator*() const { return current->value; }
+ std::conditional_t<Const, const T&, T&> operator*() const { return current->value; }
GenIterator& operator++()
{
setCurrent(next);
@@ -134,22 +134,17 @@ public:
public:
LinkedList()
- : head(0)
- , tail(0)
- , count(0)
- {}
+ : head(0), tail(0), count(0)
+ {
+ }
~LinkedList() { clear(); }
LinkedList(const LinkedList<T>& link)
- : head(0)
- , tail(0)
- , count(0)
+ : head(0), tail(0), count(0)
{
this->operator=(link);
}
LinkedList(LinkedList<T>&& link)
- : head(0)
- , tail(0)
- , count(0)
+ : head(0), tail(0), count(0)
{
this->operator=(_Move(link));
}
@@ -179,7 +174,8 @@ public:
}
return *this;
}
- template <typename IteratorFunc> void forEach(const IteratorFunc& f)
+ template<typename IteratorFunc>
+ void forEach(const IteratorFunc& f)
{
auto p = head;
while (p)
diff --git a/source/core/slang-list.h b/source/core/slang-list.h
index b1c67e438..d27afd415 100644
--- a/source/core/slang-list.h
+++ b/source/core/slang-list.h
@@ -1,11 +1,10 @@
#ifndef SLANG_CORE_LIST_H
#define SLANG_CORE_LIST_H
-#include "slang.h"
-
#include "slang-allocator.h"
-#include "slang-math.h"
#include "slang-array-view.h"
+#include "slang-math.h"
+#include "slang.h"
#include <algorithm>
#include <new>
@@ -14,626 +13,629 @@
namespace Slang
{
- // List is container of values of a type held consecutively in memory (much like std::vector)
- //
- // Note that in this implementation, the underlying memory is backed via an allocation of T[capacity]
- // This means that all values have to be in a valid state *even if they are not used* (ie indices >= m_count must be valid)
- //
- // Also note this implementation does not necessarily 'initialize' an element which is no longer used,
- // and this may lead to surprising behavior. Say the list contains a single smart pointer, and the last element is removed (say with removeLast).
- // The smart pointer will *not* be released. The smart pointer will be released if the that index is used (via say an add) or
- // the List goes out of scope.
- template<typename T, typename TAllocator = StandardAllocator>
- class List
- {
- private:
- static const Index kInitialCount = 16;
-
- public:
- typedef List ThisType;
-
- List()
- : m_buffer(nullptr), m_count(0), m_capacity(0)
- {
- }
- template<typename... Args>
- List(const T& val, Args... args)
- : m_buffer(nullptr), m_count(0), m_capacity(0)
- {
- _init(val, args...);
- }
- List(const List<T>& list)
- : m_buffer(nullptr), m_count(0), m_capacity(0)
- {
- this->operator=(list);
- }
- List(List<T>&& list)
- : m_buffer(nullptr), m_count(0), m_capacity(0)
- {
- this->operator=(static_cast<List<T>&&>(list));
- }
- List(ArrayView<T> view)
- : List()
- {
- addRange(view);
- }
- static List<T> makeRepeated(const T& val, Index count)
- {
- List<T> rs;
- rs.setCount(count);
- for (Index i = 0; i < count; i++)
- rs[i] = val;
- return rs;
- }
- ~List()
- {
- _deallocateBuffer();
- }
- List<T>& operator=(const List<T>& list)
- {
- clearAndDeallocate();
- addRange(list);
- return *this;
- }
+// List is container of values of a type held consecutively in memory (much like std::vector)
+//
+// Note that in this implementation, the underlying memory is backed via an allocation of
+// T[capacity] This means that all values have to be in a valid state *even if they are not used*
+// (ie indices >= m_count must be valid)
+//
+// Also note this implementation does not necessarily 'initialize' an element which is no longer
+// used, and this may lead to surprising behavior. Say the list contains a single smart pointer, and
+// the last element is removed (say with removeLast). The smart pointer will *not* be released. The
+// smart pointer will be released if the that index is used (via say an add) or the List goes out of
+// scope.
+template<typename T, typename TAllocator = StandardAllocator>
+class List
+{
+private:
+ static const Index kInitialCount = 16;
- List<T>& operator=(List<T>&& list)
- {
- // Could just do a swap here, and memory would be freed on rhs dtor
+public:
+ typedef List ThisType;
- _deallocateBuffer();
- m_count = list.m_count;
- m_capacity = list.m_capacity;
- m_buffer = list.m_buffer;
-
- list.m_buffer = nullptr;
- list.m_count = 0;
- list.m_capacity = 0;
- return *this;
- }
+ List()
+ : m_buffer(nullptr), m_count(0), m_capacity(0)
+ {
+ }
+ template<typename... Args>
+ List(const T& val, Args... args)
+ : m_buffer(nullptr), m_count(0), m_capacity(0)
+ {
+ _init(val, args...);
+ }
+ List(const List<T>& list)
+ : m_buffer(nullptr), m_count(0), m_capacity(0)
+ {
+ this->operator=(list);
+ }
+ List(List<T>&& list)
+ : m_buffer(nullptr), m_count(0), m_capacity(0)
+ {
+ this->operator=(static_cast<List<T>&&>(list));
+ }
+ List(ArrayView<T> view)
+ : List()
+ {
+ addRange(view);
+ }
+ static List<T> makeRepeated(const T& val, Index count)
+ {
+ List<T> rs;
+ rs.setCount(count);
+ for (Index i = 0; i < count; i++)
+ rs[i] = val;
+ return rs;
+ }
+ ~List() { _deallocateBuffer(); }
+ List<T>& operator=(const List<T>& list)
+ {
+ clearAndDeallocate();
+ addRange(list);
+ return *this;
+ }
- const T* begin() const { return m_buffer; }
- const T* end() const { return m_buffer + m_count; }
+ List<T>& operator=(List<T>&& list)
+ {
+ // Could just do a swap here, and memory would be freed on rhs dtor
- T* begin() { return m_buffer; }
- T* end() { return m_buffer + m_count; }
+ _deallocateBuffer();
+ m_count = list.m_count;
+ m_capacity = list.m_capacity;
+ m_buffer = list.m_buffer;
- const T& getFirst() const
- {
- SLANG_ASSERT(m_count > 0);
- return m_buffer[0];
- }
-
- T& getFirst()
- {
- SLANG_ASSERT(m_count > 0);
- return m_buffer[0];
- }
+ list.m_buffer = nullptr;
+ list.m_count = 0;
+ list.m_capacity = 0;
+ return *this;
+ }
- const T& getLast() const
- {
- SLANG_ASSERT(m_count > 0);
- return m_buffer[m_count - 1];
- }
+ const T* begin() const { return m_buffer; }
+ const T* end() const { return m_buffer + m_count; }
- T& getLast()
- {
- SLANG_ASSERT(m_count > 0);
- return m_buffer[m_count - 1];
- }
+ T* begin() { return m_buffer; }
+ T* end() { return m_buffer + m_count; }
- void removeLast()
- {
- SLANG_ASSERT(m_count > 0);
- m_count--;
- }
+ const T& getFirst() const
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_buffer[0];
+ }
- inline void swapWith(List<T, TAllocator>& other)
- {
- T* buffer = m_buffer;
- m_buffer = other.m_buffer;
- other.m_buffer = buffer;
+ T& getFirst()
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_buffer[0];
+ }
- auto bufferSize = m_capacity;
- m_capacity = other.m_capacity;
- other.m_capacity = bufferSize;
+ const T& getLast() const
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_buffer[m_count - 1];
+ }
- auto count = m_count;
- m_count = other.m_count;
- other.m_count = count;
- }
+ T& getLast()
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_buffer[m_count - 1];
+ }
- T* detachBuffer()
- {
- T* rs = m_buffer;
- m_buffer = nullptr;
- m_count = 0;
- m_capacity = 0;
- return rs;
- }
- void attachBuffer(T* buffer, Index count, Index capacity)
- {
- // Can only attach a buffer if there isn't a buffer already associated
- SLANG_ASSERT(m_buffer == nullptr);
- SLANG_ASSERT(count <= capacity);
- m_buffer = buffer;
- m_count = count;
- m_capacity = capacity;
- }
+ void removeLast()
+ {
+ SLANG_ASSERT(m_count > 0);
+ m_count--;
+ }
- inline ArrayView<T> getArrayView() const
- {
- return ArrayView<T>(m_buffer, m_count);
- }
+ inline void swapWith(List<T, TAllocator>& other)
+ {
+ T* buffer = m_buffer;
+ m_buffer = other.m_buffer;
+ other.m_buffer = buffer;
- inline ArrayView<T> getArrayView(Index start, Index count) const
- {
- SLANG_ASSERT(start >= 0 && count >= 0 && start + count <= m_count);
- return ArrayView<T>(m_buffer + start, count);
- }
+ auto bufferSize = m_capacity;
+ m_capacity = other.m_capacity;
+ other.m_capacity = bufferSize;
- void _maybeReserveForAdd()
- {
- if (m_capacity <= m_count)
- {
- Index newBufferSize = kInitialCount;
- if (m_capacity)
- newBufferSize = (m_capacity << 1);
+ auto count = m_count;
+ m_count = other.m_count;
+ other.m_count = count;
+ }
- reserve(newBufferSize);
- }
- }
+ T* detachBuffer()
+ {
+ T* rs = m_buffer;
+ m_buffer = nullptr;
+ m_count = 0;
+ m_capacity = 0;
+ return rs;
+ }
+ void attachBuffer(T* buffer, Index count, Index capacity)
+ {
+ // Can only attach a buffer if there isn't a buffer already associated
+ SLANG_ASSERT(m_buffer == nullptr);
+ SLANG_ASSERT(count <= capacity);
+ m_buffer = buffer;
+ m_count = count;
+ m_capacity = capacity;
+ }
- void add(T&& obj)
- {
- _maybeReserveForAdd();
- m_buffer[m_count++] = static_cast<T&&>(obj);
- }
+ inline ArrayView<T> getArrayView() const { return ArrayView<T>(m_buffer, m_count); }
- void add(const T& obj)
+ inline ArrayView<T> getArrayView(Index start, Index count) const
+ {
+ SLANG_ASSERT(start >= 0 && count >= 0 && start + count <= m_count);
+ return ArrayView<T>(m_buffer + start, count);
+ }
+
+ void _maybeReserveForAdd()
+ {
+ if (m_capacity <= m_count)
{
- _maybeReserveForAdd();
- m_buffer[m_count++] = obj;
+ Index newBufferSize = kInitialCount;
+ if (m_capacity)
+ newBufferSize = (m_capacity << 1);
+
+ reserve(newBufferSize);
}
+ }
- Index getCount() const { return m_count; }
- Index getCapacity() const { return m_capacity; }
+ void add(T&& obj)
+ {
+ _maybeReserveForAdd();
+ m_buffer[m_count++] = static_cast<T&&>(obj);
+ }
+
+ void add(const T& obj)
+ {
+ _maybeReserveForAdd();
+ m_buffer[m_count++] = obj;
+ }
- const T* getBuffer() const { return m_buffer; }
- T* getBuffer() { return m_buffer; }
+ Index getCount() const { return m_count; }
+ Index getCapacity() const { return m_capacity; }
- bool operator==(const ThisType& rhs) const
+ const T* getBuffer() const { return m_buffer; }
+ T* getBuffer() { return m_buffer; }
+
+ bool operator==(const ThisType& rhs) const
+ {
+ if (&rhs == this)
{
- if (&rhs == this)
- {
- return true;
- }
- const Index count = getCount();
- if (count != rhs.getCount())
+ return true;
+ }
+ const Index count = getCount();
+ if (count != rhs.getCount())
+ {
+ return false;
+ }
+ for (Index i = 0; i < count; ++i)
+ {
+ if ((*this)[i] != rhs[i])
{
return false;
}
- for (Index i = 0; i < count; ++i)
- {
- if ((*this)[i] != rhs[i])
- {
- return false;
- }
- }
- return true;
}
- SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
+ return true;
+ }
+ SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
- void insert(Index idx, const T& val) { insertRange(idx, &val, 1); }
+ void insert(Index idx, const T& val) { insertRange(idx, &val, 1); }
- void insertRange(Index idx, const T* vals, Index n)
+ void insertRange(Index idx, const T* vals, Index n)
+ {
+ if (m_capacity < m_count + n)
{
- if (m_capacity < m_count + n)
- {
- Index newBufferCount = kInitialCount;
- while (newBufferCount < m_count + n)
- newBufferCount = newBufferCount << 1;
+ Index newBufferCount = kInitialCount;
+ while (newBufferCount < m_count + n)
+ newBufferCount = newBufferCount << 1;
- T* newBuffer = _allocate(newBufferCount);
- if (m_capacity)
+ T* newBuffer = _allocate(newBufferCount);
+ if (m_capacity)
+ {
+ /*if (std::has_trivial_copy_assign<T>::value &&
+ std::has_trivial_destructor<T>::value)
{
- /*if (std::has_trivial_copy_assign<T>::value && std::has_trivial_destructor<T>::value)
- {
- memcpy(newBuffer, buffer, sizeof(T) * id);
- memcpy(newBuffer + id + n, buffer + id, sizeof(T) * (_count - id));
- }
- else*/
- {
- for (Index i = 0; i < idx; i++)
- newBuffer[i] = m_buffer[i];
- for (Index i = idx; i < m_count; i++)
- newBuffer[i + n] = T(static_cast<T&&>(m_buffer[i]));
- }
- _deallocateBuffer();
+ memcpy(newBuffer, buffer, sizeof(T) * id);
+ memcpy(newBuffer + id + n, buffer + id, sizeof(T) * (_count - id));
}
- m_buffer = newBuffer;
- m_capacity = newBufferCount;
- }
- else
- {
- /*if (std::has_trivial_copy_assign<T>::value && std::has_trivial_destructor<T>::value)
- memmove(buffer + id + n, buffer + id, sizeof(T) * (_count - id));
else*/
{
- for (Index i = m_count; i > idx; i--)
- m_buffer[i + n - 1] = static_cast<T&&>(m_buffer[i - 1]);
+ for (Index i = 0; i < idx; i++)
+ newBuffer[i] = m_buffer[i];
+ for (Index i = idx; i < m_count; i++)
+ newBuffer[i + n] = T(static_cast<T&&>(m_buffer[i]));
}
+ _deallocateBuffer();
}
+ m_buffer = newBuffer;
+ m_capacity = newBufferCount;
+ }
+ else
+ {
/*if (std::has_trivial_copy_assign<T>::value && std::has_trivial_destructor<T>::value)
- memcpy(buffer + id, vals, sizeof(T) * n);
+ memmove(buffer + id + n, buffer + id, sizeof(T) * (_count - id));
else*/
- for (Index i = 0; i < n; i++)
- m_buffer[idx + i] = vals[i];
-
- m_count += n;
+ {
+ for (Index i = m_count; i > idx; i--)
+ m_buffer[i + n - 1] = static_cast<T&&>(m_buffer[i - 1]);
+ }
}
+ /*if (std::has_trivial_copy_assign<T>::value && std::has_trivial_destructor<T>::value)
+ memcpy(buffer + id, vals, sizeof(T) * n);
+ else*/
+ for (Index i = 0; i < n; i++)
+ m_buffer[idx + i] = vals[i];
- void insertRange(Index id, const List<T>& list) { insertRange(id, list.m_buffer, list.m_count); }
+ m_count += n;
+ }
- void addRange(ArrayView<T> list) { insertRange(m_count, list.getBuffer(), list.getCount()); }
+ void insertRange(Index id, const List<T>& list)
+ {
+ insertRange(id, list.m_buffer, list.m_count);
+ }
- void addRange(const T* vals, Index n) { insertRange(m_count, vals, n); }
+ void addRange(ArrayView<T> list) { insertRange(m_count, list.getBuffer(), list.getCount()); }
- void addRange(const List<T>& list) { insertRange(m_count, list.m_buffer, list.m_count); }
+ void addRange(const T* vals, Index n) { insertRange(m_count, vals, n); }
- void removeRange(Index idx, Index count)
- {
- SLANG_ASSERT(idx >= 0 && idx <= m_count);
+ void addRange(const List<T>& list) { insertRange(m_count, list.m_buffer, list.m_count); }
- const Index actualDeleteCount = ((idx + count) >= m_count)? (m_count - idx) : count;
- for (Index i = idx + actualDeleteCount; i < m_count; i++)
- m_buffer[i - actualDeleteCount] = static_cast<T&&>(m_buffer[i]);
- m_count -= actualDeleteCount;
- }
+ void removeRange(Index idx, Index count)
+ {
+ SLANG_ASSERT(idx >= 0 && idx <= m_count);
+
+ const Index actualDeleteCount = ((idx + count) >= m_count) ? (m_count - idx) : count;
+ for (Index i = idx + actualDeleteCount; i < m_count; i++)
+ m_buffer[i - actualDeleteCount] = static_cast<T&&>(m_buffer[i]);
+ m_count -= actualDeleteCount;
+ }
- void removeAt(Index id) { removeRange(id, 1); }
+ void removeAt(Index id) { removeRange(id, 1); }
- void remove(const T& val)
- {
- Index idx = indexOf(val);
- if (idx != -1)
- removeAt(idx);
- }
+ void remove(const T& val)
+ {
+ Index idx = indexOf(val);
+ if (idx != -1)
+ removeAt(idx);
+ }
- void reverse()
+ void reverse()
+ {
+ for (Index i = 0; i < (m_count >> 1); i++)
{
- for (Index i = 0; i < (m_count >> 1); i++)
- {
- swapElements(m_buffer, i, m_count - i - 1);
- }
+ swapElements(m_buffer, i, m_count - i - 1);
}
+ }
- void fastRemove(const T& val)
+ void fastRemove(const T& val)
+ {
+ Index idx = indexOf(val);
+ if (idx >= 0)
{
- Index idx = indexOf(val);
- if (idx >= 0)
- {
- fastRemoveAt(idx);
- }
+ fastRemoveAt(idx);
}
+ }
- void fastRemoveAt(Index idx)
+ void fastRemoveAt(Index idx)
+ {
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
+ // We do not test for idx == m_count - 1 (ie the move is to current index). With the
+ // assumption that any reasonable move implementation tests and ignores this case
+ if (idx != m_count - 1)
{
- SLANG_ASSERT(idx >= 0 && idx < m_count);
- // We do not test for idx == m_count - 1 (ie the move is to current index). With the assumption that any reasonable move implementation
- // tests and ignores this case
- if (idx != m_count - 1)
- {
- m_buffer[idx] = _Move(m_buffer[m_count - 1]);
- }
- m_count--;
+ m_buffer[idx] = _Move(m_buffer[m_count - 1]);
}
+ m_count--;
+ }
- void clear() { m_count = 0; }
+ void clear() { m_count = 0; }
- void clearAndDeallocate()
- {
- _deallocateBuffer();
- m_count = m_capacity = 0;
- }
+ void clearAndDeallocate()
+ {
+ _deallocateBuffer();
+ m_count = m_capacity = 0;
+ }
- void reserve(Index size)
+ void reserve(Index size)
+ {
+ // The cast for this comparison is needed, otherwise some compilers erroneously detect
+ // the possiblity of a zero sized allocation (possible if m_capacity is assumed to be
+ // negative).
+ if (UIndex(size) > UIndex(m_capacity))
{
- // The cast for this comparison is needed, otherwise some compilers erroneously detect
- // the possiblity of a zero sized allocation (possible if m_capacity is assumed to be negative).
- if(UIndex(size) > UIndex(m_capacity))
+ T* newBuffer = _allocate(size);
+ if (m_capacity)
{
- T* newBuffer = _allocate(size);
- if (m_capacity)
+ /*if (std::has_trivial_copy_assign<T>::value &&
+ std::has_trivial_destructor<T>::value) memcpy(newBuffer, buffer, _count *
+ sizeof(T)); else*/
{
- /*if (std::has_trivial_copy_assign<T>::value && std::has_trivial_destructor<T>::value)
- memcpy(newBuffer, buffer, _count * sizeof(T));
- else*/
+ for (Index i = 0; i < m_count; i++)
+ newBuffer[i] = static_cast<T&&>(m_buffer[i]);
+
+ // Default-initialize the remaining elements
+ for (Index i = m_count; i < size; i++)
{
- for (Index i = 0; i < m_count; i++)
- newBuffer[i] = static_cast<T&&>(m_buffer[i]);
-
- // Default-initialize the remaining elements
- for(Index i = m_count; i < size; i++)
- {
- new(newBuffer + i) T();
- }
+ new (newBuffer + i) T();
}
- _deallocateBuffer();
}
- m_buffer = newBuffer;
- m_capacity = size;
+ _deallocateBuffer();
}
+ m_buffer = newBuffer;
+ m_capacity = size;
}
+ }
- void growToCount(Index count)
+ void growToCount(Index count)
+ {
+ Index newBufferCount = Index(1) << Math::Log2Ceil((unsigned int)count);
+ if (m_capacity < newBufferCount)
{
- Index newBufferCount = Index(1) << Math::Log2Ceil((unsigned int)count);
- if (m_capacity < newBufferCount)
- {
- reserve(newBufferCount);
- }
- m_count = count;
+ reserve(newBufferCount);
}
+ m_count = count;
+ }
- void setCount(Index count)
- {
- reserve(count);
- m_count = count;
- }
+ void setCount(Index count)
+ {
+ reserve(count);
+ m_count = count;
+ }
- void unsafeShrinkToCount(Index count) { m_count = count; }
+ void unsafeShrinkToCount(Index count) { m_count = count; }
- void compress()
+ void compress()
+ {
+ if (m_capacity > m_count && m_count > 0)
{
- if (m_capacity > m_count && m_count > 0)
- {
- T* newBuffer = _allocate(m_count);
- for (Index i = 0; i < m_count; i++)
- newBuffer[i] = static_cast<T&&>(m_buffer[i]);
+ T* newBuffer = _allocate(m_count);
+ for (Index i = 0; i < m_count; i++)
+ newBuffer[i] = static_cast<T&&>(m_buffer[i]);
- _deallocateBuffer();
- m_buffer = newBuffer;
- m_capacity = m_count;
- }
+ _deallocateBuffer();
+ m_buffer = newBuffer;
+ m_capacity = m_count;
}
+ }
- SLANG_FORCE_INLINE const T& operator [](Index idx) const
- {
- SLANG_ASSERT(idx >= 0 && idx < m_count);
- return m_buffer[idx];
- }
+ SLANG_FORCE_INLINE const T& operator[](Index idx) const
+ {
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
+ return m_buffer[idx];
+ }
- SLANG_FORCE_INLINE T& operator [](Index idx)
- {
- SLANG_ASSERT(idx >= 0 && idx < m_count);
- return m_buffer[idx];
- }
+ SLANG_FORCE_INLINE T& operator[](Index idx)
+ {
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
+ return m_buffer[idx];
+ }
- template<typename Func>
- Index findFirstIndex(const Func& predicate) const
+ template<typename Func>
+ Index findFirstIndex(const Func& predicate) const
+ {
+ for (Index i = 0; i < m_count; i++)
{
- for (Index i = 0; i < m_count; i++)
- {
- if (predicate(m_buffer[i]))
- return i;
- }
- return -1;
+ if (predicate(m_buffer[i]))
+ return i;
}
+ return -1;
+ }
- template<typename T2>
- Index indexOf(const T2& val) const
+ template<typename T2>
+ Index indexOf(const T2& val) const
+ {
+ for (Index i = 0; i < m_count; i++)
{
- for (Index i = 0; i < m_count; i++)
- {
- if (m_buffer[i] == val)
- return i;
- }
- return -1;
+ if (m_buffer[i] == val)
+ return i;
}
+ return -1;
+ }
- template<typename Func>
- Index findLastIndex(const Func& predicate) const
+ template<typename Func>
+ Index findLastIndex(const Func& predicate) const
+ {
+ for (Index i = m_count - 1; i >= 0; i--)
{
- for (Index i = m_count - 1; i >= 0; i--)
- {
- if (predicate(m_buffer[i]))
- return i;
- }
- return -1;
+ if (predicate(m_buffer[i]))
+ return i;
}
+ return -1;
+ }
- template<typename T2>
- Index lastIndexOf(const T2& val) const
+ template<typename T2>
+ Index lastIndexOf(const T2& val) const
+ {
+ for (Index i = m_count - 1; i >= 0; i--)
{
- for (Index i = m_count - 1; i >= 0; i--)
- {
- if(m_buffer[i] == val)
- return i;
- }
- return -1;
+ if (m_buffer[i] == val)
+ return i;
}
+ return -1;
+ }
- bool contains(const T& val) const { return indexOf(val) != Index(-1); }
-
- void sort()
- {
- sort([](const T& t1, const T& t2){return t1 < t2;});
- }
+ bool contains(const T& val) const { return indexOf(val) != Index(-1); }
- template<typename Comparer>
- void sort(Comparer compare)
- {
- //insertionSort(buffer, 0, _count - 1);
- //quickSort(buffer, 0, _count - 1, compare);
- std::sort(m_buffer, m_buffer + m_count, compare);
- }
+ void sort()
+ {
+ sort([](const T& t1, const T& t2) { return t1 < t2; });
+ }
- void stableSort()
- {
- stableSort([](const T& t1, const T& t2){return t1 < t2;});
- }
+ template<typename Comparer>
+ void sort(Comparer compare)
+ {
+ // insertionSort(buffer, 0, _count - 1);
+ // quickSort(buffer, 0, _count - 1, compare);
+ std::sort(m_buffer, m_buffer + m_count, compare);
+ }
- template<typename Comparer>
- void stableSort(Comparer compare)
- {
- std::stable_sort(m_buffer, m_buffer + m_count, compare);
- }
+ void stableSort()
+ {
+ stableSort([](const T& t1, const T& t2) { return t1 < t2; });
+ }
- template <typename IterateFunc>
- void forEach(IterateFunc f) const
- {
- for (Index i = 0; i < m_count; i++)
- f(m_buffer[i]);
- }
+ template<typename Comparer>
+ void stableSort(Comparer compare)
+ {
+ std::stable_sort(m_buffer, m_buffer + m_count, compare);
+ }
- template<typename Comparer>
- void quickSort(T* vals, Index startIndex, Index endIndex, Comparer comparer)
- {
- static const Index kMinQSortSize = 32;
+ template<typename IterateFunc>
+ void forEach(IterateFunc f) const
+ {
+ for (Index i = 0; i < m_count; i++)
+ f(m_buffer[i]);
+ }
- if(startIndex < endIndex)
- {
- if (endIndex - startIndex < kMinQSortSize)
- insertionSort(vals, startIndex, endIndex, comparer);
- else
- {
- Index pivotIndex = (startIndex + endIndex) >> 1;
- Index pivotNewIndex = partition(vals, startIndex, endIndex, pivotIndex, comparer);
- quickSort(vals, startIndex, pivotNewIndex - 1, comparer);
- quickSort(vals, pivotNewIndex + 1, endIndex, comparer);
- }
- }
+ template<typename Comparer>
+ void quickSort(T* vals, Index startIndex, Index endIndex, Comparer comparer)
+ {
+ static const Index kMinQSortSize = 32;
- }
- template<typename Comparer>
- Index partition(T* vals, Index left, Index right, Index pivotIndex, Comparer comparer)
+ if (startIndex < endIndex)
{
- T pivotValue = vals[pivotIndex];
- swapElements(vals, right, pivotIndex);
- Index storeIndex = left;
- for (Index i = left; i < right; i++)
+ if (endIndex - startIndex < kMinQSortSize)
+ insertionSort(vals, startIndex, endIndex, comparer);
+ else
{
- if (comparer(vals[i], pivotValue))
- {
- swapElements(vals, i, storeIndex);
- storeIndex++;
- }
+ Index pivotIndex = (startIndex + endIndex) >> 1;
+ Index pivotNewIndex = partition(vals, startIndex, endIndex, pivotIndex, comparer);
+ quickSort(vals, startIndex, pivotNewIndex - 1, comparer);
+ quickSort(vals, pivotNewIndex + 1, endIndex, comparer);
}
- swapElements(vals, storeIndex, right);
- return storeIndex;
}
- template<typename Comparer>
- void insertionSort(T* vals, Index startIndex, Index endIndex, Comparer comparer)
+ }
+ template<typename Comparer>
+ Index partition(T* vals, Index left, Index right, Index pivotIndex, Comparer comparer)
+ {
+ T pivotValue = vals[pivotIndex];
+ swapElements(vals, right, pivotIndex);
+ Index storeIndex = left;
+ for (Index i = left; i < right; i++)
{
- for (Index i = startIndex + 1; i <= endIndex; i++)
+ if (comparer(vals[i], pivotValue))
{
- T insertValue = static_cast<T&&>(vals[i]);
- Index insertIndex = i - 1;
- while (insertIndex >= startIndex && comparer(insertValue, vals[insertIndex]))
- {
- vals[insertIndex + 1] = static_cast<T&&>(vals[insertIndex]);
- insertIndex--;
- }
- vals[insertIndex + 1] = static_cast<T&&>(insertValue);
+ swapElements(vals, i, storeIndex);
+ storeIndex++;
}
}
-
- inline void swapElements(T* vals, Index index1, Index index2)
+ swapElements(vals, storeIndex, right);
+ return storeIndex;
+ }
+ template<typename Comparer>
+ void insertionSort(T* vals, Index startIndex, Index endIndex, Comparer comparer)
+ {
+ for (Index i = startIndex + 1; i <= endIndex; i++)
{
- if (index1 != index2)
+ T insertValue = static_cast<T&&>(vals[i]);
+ Index insertIndex = i - 1;
+ while (insertIndex >= startIndex && comparer(insertValue, vals[insertIndex]))
{
- T tmp = static_cast<T&&>(vals[index1]);
- vals[index1] = static_cast<T&&>(vals[index2]);
- vals[index2] = static_cast<T&&>(tmp);
+ vals[insertIndex + 1] = static_cast<T&&>(vals[insertIndex]);
+ insertIndex--;
}
+ vals[insertIndex + 1] = static_cast<T&&>(insertValue);
}
+ }
- template<typename T2, typename Comparer>
- Index binarySearch(const T2& obj, Comparer comparer) const
+ inline void swapElements(T* vals, Index index1, Index index2)
+ {
+ if (index1 != index2)
{
- Index imin = 0, imax = m_count - 1;
- while (imax >= imin)
- {
- Index imid = imin + ((imax - imin)>>1);
- int compareResult = comparer(m_buffer[imid], obj);
- if (compareResult == 0)
- return imid;
- else if (compareResult < 0)
- imin = imid + 1;
- else
- imax = imid - 1;
- }
- // TODO: The return value on a failed search should be
- // the bitwise negation of the index where `obj` should
- // be inserted to be in the proper sorted location.
- return -1;
+ T tmp = static_cast<T&&>(vals[index1]);
+ vals[index1] = static_cast<T&&>(vals[index2]);
+ vals[index2] = static_cast<T&&>(tmp);
}
+ }
- template<typename T2>
- Index binarySearch(const T2& obj)
- {
- return binarySearch(obj,
- [](T & curObj, const T2 & thatObj)->int
- {
- if (curObj < thatObj)
- return -1;
- else if (curObj == thatObj)
- return 0;
- else
- return 1;
- });
+ template<typename T2, typename Comparer>
+ Index binarySearch(const T2& obj, Comparer comparer) const
+ {
+ Index imin = 0, imax = m_count - 1;
+ while (imax >= imin)
+ {
+ Index imid = imin + ((imax - imin) >> 1);
+ int compareResult = comparer(m_buffer[imid], obj);
+ if (compareResult == 0)
+ return imid;
+ else if (compareResult < 0)
+ imin = imid + 1;
+ else
+ imax = imid - 1;
}
- private:
- T* m_buffer; ///< A new T[N] allocated buffer. NOTE! All elements up to capacity are in some valid form for T.
- Index m_capacity; ///< The total capacity of elements
- Index m_count; ///< The amount of elements
+ // TODO: The return value on a failed search should be
+ // the bitwise negation of the index where `obj` should
+ // be inserted to be in the proper sorted location.
+ return -1;
+ }
- void _deallocateBuffer()
- {
- if (m_buffer)
+ template<typename T2>
+ Index binarySearch(const T2& obj)
+ {
+ return binarySearch(
+ obj,
+ [](T& curObj, const T2& thatObj) -> int
{
- AllocateMethod<T, TAllocator>::deallocateArray(m_buffer, m_capacity);
- m_buffer = nullptr;
- }
- }
- static inline T* _allocate(Index count)
- {
- return AllocateMethod<T, TAllocator>::allocateArray(count);
- }
- static void _free(T* buffer, Index count)
- {
- return AllocateMethod<T, TAllocator>::deallocateArray(buffer, count);
- }
+ if (curObj < thatObj)
+ return -1;
+ else if (curObj == thatObj)
+ return 0;
+ else
+ return 1;
+ });
+ }
- template<typename... Args>
- void _init(const T& val, Args... args)
+private:
+ T* m_buffer; ///< A new T[N] allocated buffer. NOTE! All elements up to capacity are in some
+ ///< valid form for T.
+ Index m_capacity; ///< The total capacity of elements
+ Index m_count; ///< The amount of elements
+
+ void _deallocateBuffer()
+ {
+ if (m_buffer)
{
- add(val);
- _init(args...);
+ AllocateMethod<T, TAllocator>::deallocateArray(m_buffer, m_capacity);
+ m_buffer = nullptr;
}
-
- void _init() {}
- };
-
- template<typename T>
- T calcMin(const List<T>& list)
+ }
+ static inline T* _allocate(Index count)
{
- T minVal = list.getFirst();
- for (Index i = 1; i < list.getCount(); i++)
- if (list[i] < minVal)
- minVal = list[i];
- return minVal;
+ return AllocateMethod<T, TAllocator>::allocateArray(count);
+ }
+ static void _free(T* buffer, Index count)
+ {
+ return AllocateMethod<T, TAllocator>::deallocateArray(buffer, count);
}
- template<typename T>
- T calcMax(const List<T>& list)
+ template<typename... Args>
+ void _init(const T& val, Args... args)
{
- T maxVal = list.getFirst();
- for (Index i = 1; i< list.getCount(); i++)
- if (list[i] > maxVal)
- maxVal = list[i];
- return maxVal;
+ add(val);
+ _init(args...);
}
+
+ void _init() {}
+};
+
+template<typename T>
+T calcMin(const List<T>& list)
+{
+ T minVal = list.getFirst();
+ for (Index i = 1; i < list.getCount(); i++)
+ if (list[i] < minVal)
+ minVal = list[i];
+ return minVal;
+}
+
+template<typename T>
+T calcMax(const List<T>& list)
+{
+ T maxVal = list.getFirst();
+ for (Index i = 1; i < list.getCount(); i++)
+ if (list[i] > maxVal)
+ maxVal = list[i];
+ return maxVal;
}
+} // namespace Slang
#endif
diff --git a/source/core/slang-lz4-compression-system.cpp b/source/core/slang-lz4-compression-system.cpp
index 1e2ab9558..bb777fae6 100644
--- a/source/core/slang-lz4-compression-system.cpp
+++ b/source/core/slang-lz4-compression-system.cpp
@@ -1,10 +1,9 @@
#include "slang-lz4-compression-system.h"
+#include "slang-blob.h"
#include "slang-com-helper.h"
#include "slang-com-ptr.h"
-#include "slang-blob.h"
-
#include <lz4.h>
namespace Slang
@@ -12,31 +11,47 @@ namespace Slang
// Allocate static const storage for the various interface IDs that the Slang API needs to expose
-class LZ4CompressionSystemImpl : public RefObject, public ICompressionSystem
+class LZ4CompressionSystemImpl : public RefObject, public ICompressionSystem
{
public:
- // ISlangUnknown
+ // ISlangUnknown
// override ref counting, as singleton
SLANG_IUNKNOWN_QUERY_INTERFACE
SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
// ICompressionSystem
- virtual SLANG_NO_THROW CompressionSystemType SLANG_MCALL getSystemType() SLANG_OVERRIDE { return CompressionSystemType::LZ4; }
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compress(const CompressionStyle* style, const void* src, size_t srcSizeInBytes, ISlangBlob** outBlob) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL decompress(const void* compressed, size_t compressedSizeInBytes, size_t decompressedSizeInBytes, void* outDecompressed) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW CompressionSystemType SLANG_MCALL getSystemType() SLANG_OVERRIDE
+ {
+ return CompressionSystemType::LZ4;
+ }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compress(
+ const CompressionStyle* style,
+ const void* src,
+ size_t srcSizeInBytes,
+ ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL decompress(
+ const void* compressed,
+ size_t compressedSizeInBytes,
+ size_t decompressedSizeInBytes,
+ void* outDecompressed) SLANG_OVERRIDE;
protected:
-
ICompressionSystem* getInterface(const Guid& guid);
};
ICompressionSystem* LZ4CompressionSystemImpl::getInterface(const Guid& guid)
{
- return (guid == ISlangUnknown::getTypeGuid() || guid == ICompressionSystem::getTypeGuid()) ? static_cast<ICompressionSystem*>(this) : nullptr;
+ return (guid == ISlangUnknown::getTypeGuid() || guid == ICompressionSystem::getTypeGuid())
+ ? static_cast<ICompressionSystem*>(this)
+ : nullptr;
}
-SlangResult LZ4CompressionSystemImpl::compress(const CompressionStyle* style, const void* src, size_t srcSizeInBytes, ISlangBlob** outBlob)
+SlangResult LZ4CompressionSystemImpl::compress(
+ const CompressionStyle* style,
+ const void* src,
+ size_t srcSizeInBytes,
+ ISlangBlob** outBlob)
{
SLANG_UNUSED(style);
const size_t compressedBound = LZ4_compressBound(int(srcSizeInBytes));
@@ -44,7 +59,11 @@ SlangResult LZ4CompressionSystemImpl::compress(const CompressionStyle* style, co
ScopedAllocation alloc;
void* compressedData = alloc.allocate(compressedBound);
- const int compressedSize = LZ4_compress_default((const char*)src, (char*)compressedData, int(srcSizeInBytes), int(compressedBound));
+ const int compressedSize = LZ4_compress_default(
+ (const char*)src,
+ (char*)compressedData,
+ int(srcSizeInBytes),
+ int(compressedBound));
alloc.reallocate(compressedSize);
auto blob = RawBlob::moveCreate(alloc);
@@ -53,15 +72,23 @@ SlangResult LZ4CompressionSystemImpl::compress(const CompressionStyle* style, co
return SLANG_OK;
}
-SlangResult LZ4CompressionSystemImpl::decompress(const void* compressed, size_t compressedSizeInBytes, size_t decompressedSizeInBytes, void* outDecompressed)
+SlangResult LZ4CompressionSystemImpl::decompress(
+ const void* compressed,
+ size_t compressedSizeInBytes,
+ size_t decompressedSizeInBytes,
+ void* outDecompressed)
{
- const int decompressedSize = LZ4_decompress_safe((const char*)compressed, (char*)outDecompressed, int(compressedSizeInBytes), int(decompressedSizeInBytes));
+ const int decompressedSize = LZ4_decompress_safe(
+ (const char*)compressed,
+ (char*)outDecompressed,
+ int(compressedSizeInBytes),
+ int(decompressedSizeInBytes));
SLANG_UNUSED(decompressedSize);
SLANG_ASSERT(size_t(decompressedSize) == decompressedSizeInBytes);
return SLANG_OK;
}
-/* static */ICompressionSystem* LZ4CompressionSystem::getSingleton()
+/* static */ ICompressionSystem* LZ4CompressionSystem::getSingleton()
{
static LZ4CompressionSystemImpl impl;
return &impl;
diff --git a/source/core/slang-lz4-compression-system.h b/source/core/slang-lz4-compression-system.h
index d74fbd61a..bfc039b54 100644
--- a/source/core/slang-lz4-compression-system.h
+++ b/source/core/slang-lz4-compression-system.h
@@ -2,10 +2,8 @@
#define SLANG_LZ4_COMPRESSION_SYSTEM_H
#include "slang-basic.h"
-
-#include "slang-compression-system.h"
-
#include "slang-com-ptr.h"
+#include "slang-compression-system.h"
namespace Slang
{
@@ -17,6 +15,6 @@ public:
static ICompressionSystem* getSingleton();
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-math.h b/source/core/slang-math.h
index 51ada76a9..e977dc37d 100644
--- a/source/core/slang-math.h
+++ b/source/core/slang-math.h
@@ -2,264 +2,272 @@
#define SLANG_CORE_MATH_H
#include "slang.h"
+
#include <cmath>
namespace Slang
{
- // Some handy constants
+// Some handy constants
- // The largest positive (or negative) number
-# define SLANG_HALF_MAX 65504.0f
- // Smallest (denormalized) value. 1 / 2^24
-# define SLANG_HALF_SUB_NORMAL_MIN (1.0f / 16777216.0f)
+// The largest positive (or negative) number
+#define SLANG_HALF_MAX 65504.0f
+// Smallest (denormalized) value. 1 / 2^24
+#define SLANG_HALF_SUB_NORMAL_MIN (1.0f / 16777216.0f)
- class Math
- {
- public:
- // Use to fix type punning issues with strict aliasing
- union FloatIntUnion
- {
- float fvalue;
- int ivalue;
+class Math
+{
+public:
+ // Use to fix type punning issues with strict aliasing
+ union FloatIntUnion
+ {
+ float fvalue;
+ int ivalue;
- SLANG_FORCE_INLINE static FloatIntUnion makeFromInt(int i) { FloatIntUnion cast; cast.ivalue = i; return cast; }
- SLANG_FORCE_INLINE static FloatIntUnion makeFromFloat(float f) { FloatIntUnion cast; cast.fvalue = f; return cast; }
- };
- union DoubleInt64Union
+ SLANG_FORCE_INLINE static FloatIntUnion makeFromInt(int i)
{
- double dvalue;
- int64_t ivalue;
- SLANG_FORCE_INLINE static DoubleInt64Union makeFromInt64(int64_t i) { DoubleInt64Union cast; cast.ivalue = i; return cast; }
- SLANG_FORCE_INLINE static DoubleInt64Union makeFromDouble(double d) { DoubleInt64Union cast; cast.dvalue = d; return cast; }
- };
-
- static const float Pi;
-
- template <typename T>
- static T Abs(T a)
+ FloatIntUnion cast;
+ cast.ivalue = i;
+ return cast;
+ }
+ SLANG_FORCE_INLINE static FloatIntUnion makeFromFloat(float f)
+ {
+ FloatIntUnion cast;
+ cast.fvalue = f;
+ return cast;
+ }
+ };
+ union DoubleInt64Union
+ {
+ double dvalue;
+ int64_t ivalue;
+ SLANG_FORCE_INLINE static DoubleInt64Union makeFromInt64(int64_t i)
{
- return (a < 0) ? -a : a;
+ DoubleInt64Union cast;
+ cast.ivalue = i;
+ return cast;
}
+ SLANG_FORCE_INLINE static DoubleInt64Union makeFromDouble(double d)
+ {
+ DoubleInt64Union cast;
+ cast.dvalue = d;
+ return cast;
+ }
+ };
- template<typename T>
- static T Min(const T& v1, const T&v2)
- {
- return v1<v2?v1:v2;
- }
- template<typename T>
- static T Max(const T& v1, const T&v2)
- {
- return v1>v2?v1:v2;
- }
- template<typename T>
- static T Min(const T& v1, const T&v2, const T&v3)
- {
- return Min(v1, Min(v2, v3));
- }
- template<typename T>
- static T Max(const T& v1, const T&v2, const T&v3)
- {
- return Max(v1, Max(v2, v3));
- }
- template<typename T>
- static T Clamp(const T& val, const T& vmin, const T&vmax)
- {
- if (val < vmin) return vmin;
- else if (val > vmax) return vmax;
- else return val;
- }
+ static const float Pi;
- static inline int FastFloor(float x)
- {
- int i = (int)x;
- return i - (i > x);
- }
+ template<typename T>
+ static T Abs(T a)
+ {
+ return (a < 0) ? -a : a;
+ }
- static inline int FastFloor(double x)
- {
- int i = (int)x;
- return i - (i > x);
- }
+ template<typename T>
+ static T Min(const T& v1, const T& v2)
+ {
+ return v1 < v2 ? v1 : v2;
+ }
+ template<typename T>
+ static T Max(const T& v1, const T& v2)
+ {
+ return v1 > v2 ? v1 : v2;
+ }
+ template<typename T>
+ static T Min(const T& v1, const T& v2, const T& v3)
+ {
+ return Min(v1, Min(v2, v3));
+ }
+ template<typename T>
+ static T Max(const T& v1, const T& v2, const T& v3)
+ {
+ return Max(v1, Max(v2, v3));
+ }
+ template<typename T>
+ static T Clamp(const T& val, const T& vmin, const T& vmax)
+ {
+ if (val < vmin)
+ return vmin;
+ else if (val > vmax)
+ return vmax;
+ else
+ return val;
+ }
- static inline int IsNaN(float x)
- {
- return std::isnan(x);
- }
+ static inline int FastFloor(float x)
+ {
+ int i = (int)x;
+ return i - (i > x);
+ }
- static inline int IsInf(float x)
- {
- return std::isinf(x);
- }
+ static inline int FastFloor(double x)
+ {
+ int i = (int)x;
+ return i - (i > x);
+ }
- static inline unsigned int Ones32(unsigned int x)
- {
- /* 32-bit recursive reduction using SWAR...
- but first step is mapping 2-bit values
- into sum of 2 1-bit values in sneaky way
- */
- x -= ((x >> 1) & 0x55555555);
- x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
- x = (((x >> 4) + x) & 0x0f0f0f0f);
- x += (x >> 8);
- x += (x >> 16);
- return(x & 0x0000003f);
- }
+ static inline int IsNaN(float x) { return std::isnan(x); }
- static inline unsigned int Log2Floor(unsigned int x)
- {
- x |= (x >> 1);
- x |= (x >> 2);
- x |= (x >> 4);
- x |= (x >> 8);
- x |= (x >> 16);
- return(Ones32(x >> 1));
- }
+ static inline int IsInf(float x) { return std::isinf(x); }
- static inline unsigned int Log2Ceil(unsigned int x)
- {
- int y = (x & (x - 1));
- y |= -y;
- y >>= (32 - 1);
- x |= (x >> 1);
- x |= (x >> 2);
- x |= (x >> 4);
- x |= (x >> 8);
- x |= (x >> 16);
- return(Ones32(x >> 1) - y);
- }
- /*
- static inline int Log2(float x)
- {
- unsigned int ix = (unsigned int&)x;
- unsigned int exp = (ix >> 23) & 0xFF;
- int log2 = (unsigned int)(exp) - 127;
+ static inline unsigned int Ones32(unsigned int x)
+ {
+ /* 32-bit recursive reduction using SWAR...
+ but first step is mapping 2-bit values
+ into sum of 2 1-bit values in sneaky way
+ */
+ x -= ((x >> 1) & 0x55555555);
+ x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+ x = (((x >> 4) + x) & 0x0f0f0f0f);
+ x += (x >> 8);
+ x += (x >> 16);
+ return (x & 0x0000003f);
+ }
- return log2;
- }
- */
+ static inline unsigned int Log2Floor(unsigned int x)
+ {
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+ return (Ones32(x >> 1));
+ }
- static bool AreNearlyEqual(double a, double b, double epsilon)
- {
- // If they are equal then we are done
- if (a == b)
- {
- return true;
- }
+ static inline unsigned int Log2Ceil(unsigned int x)
+ {
+ int y = (x & (x - 1));
+ y |= -y;
+ y >>= (32 - 1);
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+ return (Ones32(x >> 1) - y);
+ }
+ /*
+ static inline int Log2(float x)
+ {
+ unsigned int ix = (unsigned int&)x;
+ unsigned int exp = (ix >> 23) & 0xFF;
+ int log2 = (unsigned int)(exp) - 127;
- const double absA = Abs(a);
- const double absB = Abs(b);
- const double diff = Abs(a - b);
+ return log2;
+ }
+ */
- // https://en.wikipedia.org/wiki/Double_precision_floating-point_format
- const double minNormal = 2.2250738585072014e-308;
- // Either a or b are very close to being zero, so doing relative comparison isn't really appropriate
- if (a == 0.0 || b == 0.0 || (absA + absB < minNormal))
- {
- return diff < (epsilon * minNormal);
- }
- else
- {
- // Calculate a relative relative error
- return diff < epsilon * (absA + absB);
- }
+ static bool AreNearlyEqual(double a, double b, double epsilon)
+ {
+ // If they are equal then we are done
+ if (a == b)
+ {
+ return true;
}
- template <typename T>
- static T getLowestBit(T val)
+ const double absA = Abs(a);
+ const double absB = Abs(b);
+ const double diff = Abs(a - b);
+
+ // https://en.wikipedia.org/wiki/Double_precision_floating-point_format
+ const double minNormal = 2.2250738585072014e-308;
+ // Either a or b are very close to being zero, so doing relative comparison isn't really
+ // appropriate
+ if (a == 0.0 || b == 0.0 || (absA + absB < minNormal))
+ {
+ return diff < (epsilon * minNormal);
+ }
+ else
{
- return val & (-val);
+ // Calculate a relative relative error
+ return diff < epsilon * (absA + absB);
}
- };
- inline int FloatAsInt(float val)
- {
- return Math::FloatIntUnion::makeFromFloat(val).ivalue;
- }
- inline float IntAsFloat(int val)
- {
- return Math::FloatIntUnion::makeFromInt(val).fvalue;
- }
+ }
+
+ template<typename T>
+ static T getLowestBit(T val)
+ {
+ return val & (-val);
+ }
+};
+inline int FloatAsInt(float val)
+{
+ return Math::FloatIntUnion::makeFromFloat(val).ivalue;
+}
+inline float IntAsFloat(int val)
+{
+ return Math::FloatIntUnion::makeFromInt(val).fvalue;
+}
- SLANG_FORCE_INLINE int64_t DoubleAsInt64(double val)
+SLANG_FORCE_INLINE int64_t DoubleAsInt64(double val)
+{
+ return Math::DoubleInt64Union::makeFromDouble(val).ivalue;
+}
+SLANG_FORCE_INLINE double Int64AsDouble(int64_t value)
+{
+ return Math::DoubleInt64Union::makeFromInt64(value).dvalue;
+}
+
+inline unsigned short FloatToHalf(float val)
+{
+ const auto x = FloatAsInt(val);
+
+ unsigned short bits = (x >> 16) & 0x8000;
+ unsigned short m = (x >> 12) & 0x07ff;
+ unsigned int e = (x >> 23) & 0xff;
+ if (e < 103)
+ return bits;
+ if (e > 142)
{
- return Math::DoubleInt64Union::makeFromDouble(val).ivalue;
+ bits |= 0x7c00u;
+ bits |= e == 255 && (x & 0x007fffffu);
+ return bits;
}
- SLANG_FORCE_INLINE double Int64AsDouble(int64_t value)
+ if (e < 113)
{
- return Math::DoubleInt64Union::makeFromInt64(value).dvalue;
+ m |= 0x0800u;
+ bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
+ return bits;
}
+ bits |= ((e - 112) << 10) | (m >> 1);
+ bits += m & 1;
+ return bits;
+}
- inline unsigned short FloatToHalf(float val)
- {
- const auto x = FloatAsInt(val);
-
- unsigned short bits = (x >> 16) & 0x8000;
- unsigned short m = (x >> 12) & 0x07ff;
- unsigned int e = (x >> 23) & 0xff;
- if (e < 103)
- return bits;
- if (e > 142)
- {
- bits |= 0x7c00u;
- bits |= e == 255 && (x & 0x007fffffu);
- return bits;
- }
- if (e < 113)
- {
- m |= 0x0800u;
- bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
- return bits;
- }
- bits |= ((e - 112) << 10) | (m >> 1);
- bits += m & 1;
- return bits;
- }
+inline float HalfToFloat(unsigned short input)
+{
+ static const auto magic = Math::FloatIntUnion::makeFromInt((127 + (127 - 15)) << 23);
+ static const auto was_infnan = Math::FloatIntUnion::makeFromInt((127 + 16) << 23);
+ Math::FloatIntUnion o;
+ o.ivalue = (input & 0x7fff) << 13; // exponent/mantissa bits
+ o.fvalue *= magic.fvalue; // exponent adjust
+ if (o.fvalue >= was_infnan.fvalue) // make sure Inf/NaN survive
+ o.ivalue |= 255 << 23;
+ o.ivalue |= (input & 0x8000) << 16; // sign bit
+ return o.fvalue;
+}
- inline float HalfToFloat(unsigned short input)
- {
- static const auto magic = Math::FloatIntUnion::makeFromInt((127 + (127 - 15)) << 23);
- static const auto was_infnan = Math::FloatIntUnion::makeFromInt((127 + 16) << 23);
- Math::FloatIntUnion o;
- o.ivalue = (input & 0x7fff) << 13; // exponent/mantissa bits
- o.fvalue *= magic.fvalue; // exponent adjust
- if (o.fvalue >= was_infnan.fvalue) // make sure Inf/NaN survive
- o.ivalue |= 255 << 23;
- o.ivalue |= (input & 0x8000) << 16; // sign bit
- return o.fvalue;
- }
+class Random
+{
+private:
+ unsigned int seed;
- class Random
- {
- private:
- unsigned int seed;
- public:
- Random(int seed)
- {
- this->seed = seed;
- }
- int Next() // random between 0 and RandMax (currently 0x7fff)
- {
- return ((seed = ((seed << 12) + 150889L) % 714025) & 0x7fff);
- }
- int Next(int min, int max) // inclusive min, exclusive max
- {
- unsigned int a = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF);
- unsigned int b = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF);
- unsigned int r = (a << 16) + b;
- return min + r % (max - min);
- }
- float NextFloat()
- {
- return ((Next() << 15) + Next()) / ((float)(1 << 30));
- }
- float NextFloat(float valMin, float valMax)
- {
- return valMin + (valMax - valMin) * NextFloat();
- }
- static int RandMax()
- {
- return 0x7fff;
- }
- };
-}
+public:
+ Random(int seed) { this->seed = seed; }
+ int Next() // random between 0 and RandMax (currently 0x7fff)
+ {
+ return ((seed = ((seed << 12) + 150889L) % 714025) & 0x7fff);
+ }
+ int Next(int min, int max) // inclusive min, exclusive max
+ {
+ unsigned int a = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF);
+ unsigned int b = ((seed = ((seed << 12) + 150889L) % 714025) & 0xFFFF);
+ unsigned int r = (a << 16) + b;
+ return min + r % (max - min);
+ }
+ float NextFloat() { return ((Next() << 15) + Next()) / ((float)(1 << 30)); }
+ float NextFloat(float valMin, float valMax) { return valMin + (valMax - valMin) * NextFloat(); }
+ static int RandMax() { return 0x7fff; }
+};
+} // namespace Slang
-#endif
+#endif
diff --git a/source/core/slang-memory-arena.cpp b/source/core/slang-memory-arena.cpp
index 6a13addb6..cb1d3c577 100644
--- a/source/core/slang-memory-arena.cpp
+++ b/source/core/slang-memory-arena.cpp
@@ -1,7 +1,8 @@
#include "slang-memory-arena.h"
-namespace Slang {
+namespace Slang
+{
MemoryArena::MemoryArena()
{
@@ -34,13 +35,13 @@ void MemoryArena::init(size_t blockPayloadSize, size_t blockAlignment)
reset();
_initialize(blockPayloadSize, blockAlignment);
}
-
+
void MemoryArena::_initialize(size_t blockPayloadSize, size_t alignment)
{
// Alignment must be a power of 2
assert(((alignment - 1) & alignment) == 0);
- // Ensure it's alignment is at least kMinAlignment
+ // Ensure it's alignment is at least kMinAlignment
alignment = (alignment < kMinAlignment) ? kMinAlignment : alignment;
const size_t alignMask = alignment - 1;
@@ -52,12 +53,13 @@ void MemoryArena::_initialize(size_t blockPayloadSize, size_t alignment)
// If alignment required is larger then the backing allocators then
// make larger to ensure when alignment correction takes place it will be aligned
- const size_t blockAllocSize = (alignment > kMinAlignment) ? (blockPayloadSize + alignment) : blockPayloadSize;
-
+ const size_t blockAllocSize =
+ (alignment > kMinAlignment) ? (blockPayloadSize + alignment) : blockPayloadSize;
+
m_blockAllocSize = blockAllocSize;
m_blockAlignment = alignment;
m_availableBlocks = nullptr;
-
+
m_blockFreeList.init(sizeof(Block), sizeof(void*), 16);
_resetCurrentBlock();
@@ -137,9 +139,11 @@ void MemoryArena::_deallocateBlocks(Block* start)
bool MemoryArena::_isNormalBlock(Block* block)
{
- // The size of the block in total is from m_alloc to the m_end (ie the size that is passed into _newBlock)
+ // The size of the block in total is from m_alloc to the m_end (ie the size that is passed into
+ // _newBlock)
const size_t blockSize = size_t(block->m_end - block->m_alloc);
- return (blockSize == m_blockAllocSize) && ((size_t(block->m_start) & (m_blockAlignment - 1)) == 0);
+ return (blockSize == m_blockAllocSize) &&
+ ((size_t(block->m_start) & (m_blockAlignment - 1)) == 0);
}
void MemoryArena::_deallocateBlock(Block* block)
@@ -169,7 +173,7 @@ void MemoryArena::deallocateAll()
_deallocateBlock(block);
block = next;
}
-
+
// Reset current block
_resetCurrentBlock();
}
@@ -341,14 +345,17 @@ void* MemoryArena::_allocateAlignedFromNewBlock(size_t size, size_t alignment)
// There are two scenarios
// a) Allocate a new normal block and make current
// b) Allocate a new 'odd-sized' block and make current
- //
- // That by always allocating a new block if odd-sized, we lose more efficiency in terms of storage (the previous block
- // may not have been used much). BUT doing so makes it easy to rewind - as the blocks are always in order of allocation.
//
- // An improvement might be to have some abstraction that sits on top that can do this tracking (or have the blocks
- // themselves record if they alias over a previously used block - but we don't bother with this here.
- // If the alignment is greater than regular alignment we need to handle specially
- if (allocSize > m_blockPayloadSize || (alignment > m_blockAlignment && allocSize + alignment > m_blockPayloadSize))
+ // That by always allocating a new block if odd-sized, we lose more efficiency in terms of
+ // storage (the previous block may not have been used much). BUT doing so makes it easy to
+ // rewind - as the blocks are always in order of allocation.
+ //
+ // An improvement might be to have some abstraction that sits on top that can do this tracking
+ // (or have the blocks themselves record if they alias over a previously used block - but we
+ // don't bother with this here. If the alignment is greater than regular alignment we need to
+ // handle specially
+ if (allocSize > m_blockPayloadSize ||
+ (alignment > m_blockAlignment && allocSize + alignment > m_blockPayloadSize))
{
// This is an odd-sized block so just allocate the whole thing.
block = _newBlock(allocSize, alignment);
@@ -366,10 +373,10 @@ void* MemoryArena::_allocateAlignedFromNewBlock(size_t size, size_t alignment)
return nullptr;
}
- // Make the current block
+ // Make the current block
_addCurrentBlock(block);
- // Align the memory
+ // Align the memory
uint8_t* memory = (uint8_t*)((size_t(m_current) + alignMask) & ~alignMask);
// It must be aligned
@@ -413,14 +420,14 @@ void MemoryArena::_rewindToCursor(const void* cursorIn)
deallocateAll();
return;
}
-
+
// Find the block that contains the allocation
Block* cursorBlock = _findNonCurrent(cursorIn);
assert(cursorBlock);
if (!cursorBlock)
{
// If not found it means this address is NOT part any of the active used heap!
- // Probably an invalid cursor
+ // Probably an invalid cursor
return;
}
@@ -436,7 +443,7 @@ void MemoryArena::_rewindToCursor(const void* cursorIn)
}
// The cursor block is now the current block
- m_usedBlocks = cursorBlock;
+ m_usedBlocks = cursorBlock;
_setCurrentBlock(cursorBlock);
const uint8_t* cursor = (const uint8_t*)cursorIn;
@@ -450,13 +457,12 @@ void MemoryArena::_rewindToCursor(const void* cursorIn)
size_t MemoryArena::calcTotalMemoryUsed() const
{
return (m_usedBlocks ? _calcBlocksUsedMemory(m_usedBlocks->m_next) : 0) +
- size_t(m_current - m_start);
+ size_t(m_current - m_start);
}
size_t MemoryArena::calcTotalMemoryAllocated() const
{
- return _calcBlocksAllocatedMemory(m_usedBlocks) +
- _calcBlocksAllocatedMemory(m_availableBlocks);
+ return _calcBlocksAllocatedMemory(m_usedBlocks) + _calcBlocksAllocatedMemory(m_availableBlocks);
}
diff --git a/source/core/slang-memory-arena.h b/source/core/slang-memory-arena.h
index cbd0fdc56..03631befe 100644
--- a/source/core/slang-memory-arena.h
+++ b/source/core/slang-memory-arena.h
@@ -1,179 +1,194 @@
#ifndef SLANG_CORE_MEMORY_ARENA_H
#define SLANG_CORE_MEMORY_ARENA_H
+#include "slang-free-list.h"
#include "slang.h"
#include <stdlib.h>
#include <string.h>
-
#include <type_traits>
-#include "slang-free-list.h"
+namespace Slang
+{
-namespace Slang {
+/** MemoryArena provides provides very fast allocation of small blocks, by aggregating many small
+allocations over smaller amount of larger blocks. A typical small unaligned allocation is a pointer
+bump.
-/** MemoryArena provides provides very fast allocation of small blocks, by aggregating many small allocations
-over smaller amount of larger blocks. A typical small unaligned allocation is a pointer bump.
+Allocations are made contiguously from the current block. If there is no space in the current block,
+the next block (which is unused) if available is checked. If that works, an allocation is made from
+the next block. If not a new block is allocated that can hold at least the allocation with required
+alignment.
-Allocations are made contiguously from the current block. If there is no space in the current block, the
-next block (which is unused) if available is checked. If that works, an allocation is made from the next block.
-If not a new block is allocated that can hold at least the allocation with required alignment.
-
-All memory allocated can be deallocated very quickly and without a client having to track any memory.
-All memory allocated will be freed on destruction - or with reset.
+All memory allocated can be deallocated very quickly and without a client having to track any
+memory. All memory allocated will be freed on destruction - or with reset.
-A memory arena can have requests larger than the block size. When that happens they will just be allocated
-from the heap. As such 'odd blocks' are seen as unusual and potentially wasteful so they are deallocated
-when deallocateAll is called, whereas regular size blocks will remain allocated for fast subsequent allocation.
+A memory arena can have requests larger than the block size. When that happens they will just be
+allocated from the heap. As such 'odd blocks' are seen as unusual and potentially wasteful so they
+are deallocated when deallocateAll is called, whereas regular size blocks will remain allocated for
+fast subsequent allocation.
It is intentional that blocks information is stored separately from the allocations that store the
-user data. This is so that alignment permitting, block allocations sizes can be passed directly to underlying allocator.
-For large power of 2 backing allocations this might mean a page/pages directly allocated by the OS for example.
-Also means better cache coherency when traversing blocks -> as generally they will be contiguous in memory.
-
-Note that allocateUnaligned can be used for slightly faster aligned allocations. All blocks allocated internally
-are aligned to the blockAlignment passed to the constructor. If subsequent allocations (of any type) sizes are of that
-alignment or larger then no alignment fixing is required (because allocations are contiguous) and so 'allocateUnaligned'
-will return allocations of blockAlignment alignment.
-
-If many 'odd' allocations occur it probably means that the block size should be increased.
+user data. This is so that alignment permitting, block allocations sizes can be passed directly to
+underlying allocator. For large power of 2 backing allocations this might mean a page/pages directly
+allocated by the OS for example. Also means better cache coherency when traversing blocks -> as
+generally they will be contiguous in memory.
+
+Note that allocateUnaligned can be used for slightly faster aligned allocations. All blocks
+allocated internally are aligned to the blockAlignment passed to the constructor. If subsequent
+allocations (of any type) sizes are of that alignment or larger then no alignment fixing is required
+(because allocations are contiguous) and so 'allocateUnaligned' will return allocations of
+blockAlignment alignment.
+
+If many 'odd' allocations occur it probably means that the block size should be increased.
*/
class MemoryArena
{
public:
typedef MemoryArena ThisType;
- /** The minimum alignment of the backing memory allocator.
- NOTE! That this should not be greater than the alignment of the underlying allocator, and should never be less than sizeof(void*).
- */
- static const size_t kMinAlignment = sizeof(void*);
- /** Determines if an allocation is consistent with an allocation from this arena.
-
- The test cannot say definitively if this was such an allocation, because the exact details
- of each allocation are not kept.
- @param alloc The start of the allocation
- @param sizeInBytes The size of the allocation in bytes
- @return true if allocation could have been from this Arena */
+ /** The minimum alignment of the backing memory allocator.
+ NOTE! That this should not be greater than the alignment of the underlying allocator, and should
+ never be less than sizeof(void*).
+ */
+ static const size_t kMinAlignment = sizeof(void*);
+ /** Determines if an allocation is consistent with an allocation from this arena.
+
+ The test cannot say definitively if this was such an allocation, because the exact details
+ of each allocation are not kept.
+ @param alloc The start of the allocation
+ @param sizeInBytes The size of the allocation in bytes
+ @return true if allocation could have been from this Arena */
bool isValid(const void* alloc, size_t sizeInBytes) const;
- /** Initialize the arena with specified block size and alignment
- If the arena has been previously initialized will free and deallocate all memory */
+ /** Initialize the arena with specified block size and alignment
+ If the arena has been previously initialized will free and deallocate all memory */
void init(size_t blockSizeInBytes, size_t blockAlignment = kMinAlignment);
- /** Allocate some memory of at least size bytes without having any specific alignment.
+ /** Allocate some memory of at least size bytes without having any specific alignment.
- Can be used for slightly faster *aligned* allocations if caveats in class description are met. Alignment is kMinAlignment or better.
+ Can be used for slightly faster *aligned* allocations if caveats in class description are met.
+ Alignment is kMinAlignment or better.
- @param size The size of the allocation requested (in bytes and must be > 0).
- @return The allocation. Can be nullptr if backing allocator was not able to request required memory */
+ @param size The size of the allocation requested (in bytes and must be > 0).
+ @return The allocation. Can be nullptr if backing allocator was not able to request required
+ memory */
void* allocate(size_t sizeInBytes);
- /** Same as allocate, but zeros memory before returning
- @param size The size of the allocation requested (in bytes and must be > 0).
- @return The allocation. Can be nullptr if backing allocator was not able to request required memory */
- void* allocateAndZero(size_t sizeInBytes);
-
- /** Allocate some aligned memory of at least size bytes
- @param size Size of allocation wanted (must be > 0).
- @param alignment Alignment of allocation - must be a power of 2.
- @return The allocation (or nullptr if unable to allocate). Will be at least 'alignment' alignment or better. */
+ /** Same as allocate, but zeros memory before returning
+ @param size The size of the allocation requested (in bytes and must be > 0).
+ @return The allocation. Can be nullptr if backing allocator was not able to request required
+ memory */
+ void* allocateAndZero(size_t sizeInBytes);
+
+ /** Allocate some aligned memory of at least size bytes
+ @param size Size of allocation wanted (must be > 0).
+ @param alignment Alignment of allocation - must be a power of 2.
+ @return The allocation (or nullptr if unable to allocate). Will be at least 'alignment'
+ alignment or better. */
void* allocateAligned(size_t sizeInBytes, size_t alignment);
- /** Allocate some aligned memory of at least size bytes
- @param sizeInBytes Size of allocation wanted (must be > 0).
- @return The allocation (or nullptr if unable to allocate). */
+ /** Allocate some aligned memory of at least size bytes
+ @param sizeInBytes Size of allocation wanted (must be > 0).
+ @return The allocation (or nullptr if unable to allocate). */
void* allocateUnaligned(size_t sizeInBytes);
- /** Allocate some aligned memory of at least size bytes, without alignment, and only from current block.
- @param sizeInBytes Size of allocation wanted.
- @return The allocation (or nullptr if unable to allocate in current block). */
+ /** Allocate some aligned memory of at least size bytes, without alignment, and only from
+ current block.
+ @param sizeInBytes Size of allocation wanted.
+ @return The allocation (or nullptr if unable to allocate in current block). */
void* allocateCurrentUnaligned(size_t sizeInBytes);
- /** Allocates a null terminated string.
+ /** Allocates a null terminated string.
- NOTE, it is not possible to rewind to a zero length string allocation (because such a strings memory is not held on the arena)
+ NOTE, it is not possible to rewind to a zero length string allocation (because such a strings
+ memory is not held on the arena)
- @param str A null-terminated string
- @return A copy of the string held on the arena */
+ @param str A null-terminated string
+ @return A copy of the string held on the arena */
const char* allocateString(const char* str);
- /** Allocates a null terminated string.
- @param chars Pointer to first character
- @param charCount The amount of characters NOT including terminating 0.
- @return A copy of the string held on the arena. */
+ /** Allocates a null terminated string.
+ @param chars Pointer to first character
+ @param charCount The amount of characters NOT including terminating 0.
+ @return A copy of the string held on the arena. */
const char* allocateString(const char* chars, size_t numChars);
- /// Allocate space for the specified type, with appropriate alignment. Note: Constructor for type is *NOT* executed.
- template <typename T>
+ /// Allocate space for the specified type, with appropriate alignment. Note: Constructor for
+ /// type is *NOT* executed.
+ template<typename T>
T* allocate();
- /// Allocate an array of a specified type. NOTE Constructor of T is *NOT* executed.
- template <typename T>
+ /// Allocate an array of a specified type. NOTE Constructor of T is *NOT* executed.
+ template<typename T>
T* allocateArray(size_t numElems);
- /// Allocate an array of a specified type, and copy array passed into it.
- template <typename T>
- T* allocateAndCopyArray(const T* src, size_t numElems);
+ /// Allocate an array of a specified type, and copy array passed into it.
+ template<typename T>
+ T* allocateAndCopyArray(const T* src, size_t numElems);
- /// Allocate an array of a specified type, and zero it.
- template <typename T>
+ /// Allocate an array of a specified type, and zero it.
+ template<typename T>
T* allocateAndZeroArray(size_t numElems);
- /** Deallocates all allocated memory. That backing memory will generally not be released so
- subsequent allocation will be fast, and from the same memory. Note though that 'odd' blocks
- will be deallocated. */
+ /** Deallocates all allocated memory. That backing memory will generally not be released so
+ subsequent allocation will be fast, and from the same memory. Note though that 'odd' blocks
+ will be deallocated. */
void deallocateAll();
- /// Resets to the initial state when constructed (and all backing memory will be deallocated)
+ /// Resets to the initial state when constructed (and all backing memory will be deallocated)
void reset();
- /// Adjusts such that the next allocate will be at least to the block alignment.
+ /// Adjusts such that the next allocate will be at least to the block alignment.
void adjustToBlockAlignment();
-
- /// Gets the block alignment that is passed at initialization otherwise 0 an invalid block alignment.
+
+ /// Gets the block alignment that is passed at initialization otherwise 0 an invalid block
+ /// alignment.
size_t getBlockAlignment() const { return m_blockAlignment; }
- /// Get the default block payload size
+ /// Get the default block payload size
size_t getBlockPayloadSize() const { return m_blockPayloadSize; }
- /// Estimate of total amount of memory used in bytes. The number can never be smaller than actual used memory but may be larger
+ /// Estimate of total amount of memory used in bytes. The number can never be smaller than
+ /// actual used memory but may be larger
size_t calcTotalMemoryUsed() const;
- /// Total memory allocated in bytes
+ /// Total memory allocated in bytes
size_t calcTotalMemoryAllocated() const;
- /// Get the current allocation cursor (memory address where subsequent allocations will be placed if space within the current block)
- /// The address of an allocated block can be used as a cursor to rewind to, such that it and all subsequent allocations will be deallocated
+ /// Get the current allocation cursor (memory address where subsequent allocations will be
+ /// placed if space within the current block) The address of an allocated block can be used as a
+ /// cursor to rewind to, such that it and all subsequent allocations will be deallocated
void* getCursor() const { return m_current; }
- /// Rewind (and effectively deallocate) all allocations *after* the cursor
+ /// Rewind (and effectively deallocate) all allocations *after* the cursor
void rewindToCursor(const void* cursor);
- /// Add a block such that it will be freed when everything else is freed.
+ /// Add a block such that it will be freed when everything else is freed.
void addExternalBlock(void* data, size_t size);
- // Swap this with rhs
+ // Swap this with rhs
void swapWith(ThisType& rhs);
- /// Default Ctor
+ /// Default Ctor
MemoryArena();
- /// Construct with block size and alignment. Block alignment must be a power of 2.
+ /// Construct with block size and alignment. Block alignment must be a power of 2.
MemoryArena(size_t blockPayloadSize, size_t blockAlignment = kMinAlignment);
- /// Dtor
+ /// Dtor
~MemoryArena();
protected:
struct Block
{
- Block* m_next; ///< Singly linked list of blocks
- uint8_t* m_alloc; ///< Allocation start (ie what to free)
- uint8_t* m_start; ///< Start of payload (takes into account alignment)
- uint8_t* m_end; ///< End of payload (m_start to m_end defines payload)
+ Block* m_next; ///< Singly linked list of blocks
+ uint8_t* m_alloc; ///< Allocation start (ie what to free)
+ uint8_t* m_start; ///< Start of payload (takes into account alignment)
+ uint8_t* m_end; ///< End of payload (m_start to m_end defines payload)
};
void _initialize(size_t blockPayloadSize, size_t blockAlignment);
- /// Delete the linked list of blocks specified by start
+ /// Delete the linked list of blocks specified by start
void _deallocateBlocks(Block* start);
- /// Delete the linked list of blocks payloads specified by start
+ /// Delete the linked list of blocks payloads specified by start
void _deallocateBlocksPayload(Block* start);
void _resetCurrentBlock();
@@ -182,44 +197,48 @@ protected:
void _deallocateBlock(Block* block);
- /// Create a new block with regular block alignment
+ /// Create a new block with regular block alignment
Block* _newNormalBlock();
- /// Allocates a new block with allocSize and alignment
+ /// Allocates a new block with allocSize and alignment
Block* _newBlock(size_t allocSizeInBytes, size_t alignment);
void* _allocateAlignedFromNewBlock(size_t sizeInBytes, size_t alignment);
void* _allocateAlignedFromNewBlockAndZero(size_t sizeInBytes, size_t alignment);
- /// Find block that contains data/size that is _NOT_ current (ie not first block in m_usedBlocks)
+ /// Find block that contains data/size that is _NOT_ current (ie not first block in
+ /// m_usedBlocks)
Block* _findNonCurrent(const void* data, size_t sizeInBytes) const;
Block* _findNonCurrent(const void* data) const;
- /// Find a block that contains data starting from block. Returns null ptr if not found
+ /// Find a block that contains data starting from block. Returns null ptr if not found
Block* _findInBlocks(Block* block, const void* data) const;
Block* _findInBlocks(Block* block, const void* data, size_t sizeInBytes) const;
size_t _calcBlocksUsedMemory(const Block* block) const;
size_t _calcBlocksAllocatedMemory(const Block* block) const;
- /// Returns true if block can be classed as normal (right size and same or better alignment)
+ /// Returns true if block can be classed as normal (right size and same or better alignment)
bool _isNormalBlock(Block* block);
- /// Handles the rewinding of the cursor for the more complicated cases
+ /// Handles the rewinding of the cursor for the more complicated cases
void _rewindToCursor(const void* cursor);
- uint8_t* m_start; ///< The start of the current block (pointed to by m_usedBlocks)
- uint8_t* m_end; ///< The end of the current block
- uint8_t* m_current; ///< The current position in current block
+ uint8_t* m_start; ///< The start of the current block (pointed to by m_usedBlocks)
+ uint8_t* m_end; ///< The end of the current block
+ uint8_t* m_current; ///< The current position in current block
+
+ size_t m_blockPayloadSize; ///< The size of the payload of a block
+ size_t m_blockAllocSize; ///< The size of a block allocation (must be the same size or bigger
+ ///< than m_blockPayloadSize)
+ size_t m_blockAlignment; ///< The alignment applied to used blocks
- size_t m_blockPayloadSize; ///< The size of the payload of a block
- size_t m_blockAllocSize; ///< The size of a block allocation (must be the same size or bigger than m_blockPayloadSize)
- size_t m_blockAlignment; ///< The alignment applied to used blocks
+ Block* m_availableBlocks; ///< Standard sized blocks that are available
+ Block*
+ m_usedBlocks; ///< Singly linked list of used blocks. The first one is the 'current block'
+ ///< and m_next is the previously allocated blocks. nullptr terminated.
- Block* m_availableBlocks; ///< Standard sized blocks that are available
- Block* m_usedBlocks; ///< Singly linked list of used blocks. The first one is the 'current block' and m_next is the previously allocated blocks. nullptr terminated.
-
- FreeList m_blockFreeList; ///< Holds all of the blocks for fast allocation/free
+ FreeList m_blockFreeList; ///< Holds all of the blocks for fast allocation/free
- private:
+private:
// Disable
MemoryArena(const ThisType& rhs) = delete;
void operator=(const ThisType& rhs) = delete;
@@ -293,20 +312,21 @@ SLANG_FORCE_INLINE void* MemoryArena::allocateAndZero(size_t sizeInBytes)
assert(sizeInBytes > 0);
// Align with the minimum alignment
const size_t alignMask = kMinAlignment - 1;
- // Implement without calling ::allocate, because in most common case we don't need to test for null.
+ // Implement without calling ::allocate, because in most common case we don't need to test for
+ // null.
uint8_t* mem = (uint8_t*)((size_t(m_current) + alignMask) & ~alignMask);
uint8_t* end = mem + sizeInBytes;
- if ( end <= m_end)
+ if (end <= m_end)
{
::memset(mem, 0, sizeInBytes);
- m_current = end;
+ m_current = end;
return mem;
}
else
{
return _allocateAlignedFromNewBlockAndZero(sizeInBytes, kMinAlignment);
}
-}
+}
// --------------------------------------------------------------------------
SLANG_FORCE_INLINE void* MemoryArena::allocateAligned(size_t sizeInBytes, size_t alignment)
@@ -356,25 +376,29 @@ inline const char* MemoryArena::allocateString(const char* chars, size_t numChar
// Add null-terminating zero
dst[numChars] = 0;
return dst;
-}
+}
// --------------------------------------------------------------------------
-template <typename T>
+template<typename T>
SLANG_FORCE_INLINE T* MemoryArena::allocate()
{
- void* mem = (SLANG_ALIGN_OF(T) <= kMinAlignment) ? allocate(sizeof(T)) : allocateAligned(sizeof(T), SLANG_ALIGN_OF(T));
+ void* mem = (SLANG_ALIGN_OF(T) <= kMinAlignment)
+ ? allocate(sizeof(T))
+ : allocateAligned(sizeof(T), SLANG_ALIGN_OF(T));
return reinterpret_cast<T*>(mem);
}
// --------------------------------------------------------------------------
-template <typename T>
+template<typename T>
SLANG_FORCE_INLINE T* MemoryArena::allocateArray(size_t numElems)
{
- return (numElems > 0) ? reinterpret_cast<T*>(allocateAligned(sizeof(T) * numElems, SLANG_ALIGN_OF(T))) : nullptr;
+ return (numElems > 0)
+ ? reinterpret_cast<T*>(allocateAligned(sizeof(T) * numElems, SLANG_ALIGN_OF(T)))
+ : nullptr;
}
// --------------------------------------------------------------------------
-template <typename T>
+template<typename T>
SLANG_FORCE_INLINE T* MemoryArena::allocateAndCopyArray(const T* arr, size_t numElems)
{
static_assert(std::is_trivially_copyable_v<T>);
@@ -389,7 +413,7 @@ SLANG_FORCE_INLINE T* MemoryArena::allocateAndCopyArray(const T* arr, size_t num
}
// ---------------------------------------------------------------------------
-template <typename T>
+template<typename T>
SLANG_FORCE_INLINE T* MemoryArena::allocateAndZeroArray(size_t numElems)
{
if (numElems > 0)
@@ -409,12 +433,13 @@ inline void MemoryArena::adjustToBlockAlignment()
uint8_t* ptr = (uint8_t*)((size_t(m_current) + alignMask) & ~alignMask);
// Alignment might push beyond end of block... if so allocate a new block
- // This test could be avoided if we aligned m_end, but depending on block alignment that might waste some space
+ // This test could be avoided if we aligned m_end, but depending on block alignment that might
+ // waste some space
if (ptr > m_end)
{
// We'll need a new block to make this alignment. Allocate a byte, and then rewind it.
_allocateAlignedFromNewBlock(1, 1);
- m_current = m_usedBlocks->m_start;
+ m_current = m_usedBlocks->m_start;
}
else
{
diff --git a/source/core/slang-memory-file-system.cpp b/source/core/slang-memory-file-system.cpp
index b24abc20b..2bca497e2 100644
--- a/source/core/slang-memory-file-system.cpp
+++ b/source/core/slang-memory-file-system.cpp
@@ -1,10 +1,9 @@
#include "slang-memory-file-system.h"
// For Path::
-#include "slang-io.h"
#include "slang-blob.h"
-
#include "slang-implicit-directory-collector.h"
+#include "slang-io.h"
namespace Slang
{
@@ -16,11 +15,9 @@ MemoryFileSystem::MemoryFileSystem()
void* MemoryFileSystem::getInterface(const Guid& guid)
{
- if ( guid == ISlangUnknown::getTypeGuid() ||
- guid == ISlangCastable::getTypeGuid() ||
- guid == ISlangFileSystem::getTypeGuid() ||
- guid == ISlangFileSystemExt::getTypeGuid() ||
- guid == ISlangMutableFileSystem::getTypeGuid())
+ if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangCastable::getTypeGuid() ||
+ guid == ISlangFileSystem::getTypeGuid() || guid == ISlangFileSystemExt::getTypeGuid() ||
+ guid == ISlangMutableFileSystem::getTypeGuid())
{
return static_cast<ISlangMutableFileSystem*>(this);
}
@@ -42,9 +39,9 @@ void* MemoryFileSystem::castAs(const Guid& guid)
return getObject(guid);
}
-void MemoryFileSystem::_clear()
-{
- m_entries = Dictionary<String, Entry>();
+void MemoryFileSystem::_clear()
+{
+ m_entries = Dictionary<String, Entry>();
}
MemoryFileSystem::Entry* MemoryFileSystem::_getEntryFromCanonicalPath(const String& canonicalPath)
@@ -90,7 +87,7 @@ SlangResult MemoryFileSystem::loadFile(char const* path, ISlangBlob** outBlob)
{
Entry* entry;
SLANG_RETURN_ON_FAIL(_loadFile(path, &entry));
-
+
ISlangBlob* contents = entry->m_contents;
contents->addRef();
*outBlob = contents;
@@ -98,22 +95,28 @@ SlangResult MemoryFileSystem::loadFile(char const* path, ISlangBlob** outBlob)
return SLANG_OK;
}
-SlangResult MemoryFileSystem::getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity)
+SlangResult MemoryFileSystem::getFileUniqueIdentity(
+ const char* path,
+ ISlangBlob** outUniqueIdentity)
{
return getPath(PathKind::Canonical, path, outUniqueIdentity);
}
-SlangResult MemoryFileSystem::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
+SlangResult MemoryFileSystem::calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut)
{
String combinedPath;
switch (fromPathType)
{
- case SLANG_PATH_TYPE_FILE:
+ case SLANG_PATH_TYPE_FILE:
{
combinedPath = Path::combine(Path::getParentDirectory(fromPath), path);
break;
}
- case SLANG_PATH_TYPE_DIRECTORY:
+ case SLANG_PATH_TYPE_DIRECTORY:
{
combinedPath = Path::combine(fromPath, path);
break;
@@ -139,26 +142,29 @@ SlangResult MemoryFileSystem::getPath(PathKind kind, const char* path, ISlangBlo
{
switch (kind)
{
- case PathKind::Simplified:
+ case PathKind::Simplified:
{
String simplifiedPath = Path::simplify(path);
*outPath = StringBlob::moveCreate(simplifiedPath).detach();
return SLANG_OK;
}
- case PathKind::Display:
- case PathKind::Canonical:
+ case PathKind::Display:
+ case PathKind::Canonical:
{
StringBuilder buffer;
SLANG_RETURN_ON_FAIL(_getCanonical(path, buffer));
*outPath = StringBlob::moveCreate(buffer).detach();
return SLANG_OK;
}
- default: break;
+ default: break;
}
return SLANG_E_NOT_AVAILABLE;
}
-SlangResult MemoryFileSystem::enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData)
+SlangResult MemoryFileSystem::enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData)
{
String canonicalPath;
Entry* entry = _getEntryFromPath(path, &canonicalPath);
@@ -204,11 +210,16 @@ SlangResult MemoryFileSystem::saveFileBlob(const char* path, ISlangBlob* dataBlo
SlangResult MemoryFileSystem::_getCanonical(const char* path, StringBuilder& outCanonicalPath)
{
StringBuilder canonicalPath;
- SLANG_RETURN_ON_FAIL(Path::simplify(UnownedStringSlice(path), Path::SimplifyStyle::AbsoluteOnlyAndNoRoot, outCanonicalPath));
+ SLANG_RETURN_ON_FAIL(Path::simplify(
+ UnownedStringSlice(path),
+ Path::SimplifyStyle::AbsoluteOnlyAndNoRoot,
+ outCanonicalPath));
return SLANG_OK;
}
-SlangResult MemoryFileSystem::_getCanonicalWithExistingParent(const char* path, StringBuilder& outCanonicalPath)
+SlangResult MemoryFileSystem::_getCanonicalWithExistingParent(
+ const char* path,
+ StringBuilder& outCanonicalPath)
{
SLANG_RETURN_ON_FAIL(_getCanonical(path, outCanonicalPath));
@@ -224,7 +235,7 @@ SlangResult MemoryFileSystem::_getCanonicalWithExistingParent(const char* path,
return SLANG_E_NOT_FOUND;
}
}
-
+
return SLANG_OK;
}
@@ -255,7 +266,9 @@ SlangResult MemoryFileSystem::_requireFile(const char* path, Entry** outEntry)
}
// It must be found and be a file
- SLANG_ASSERT(foundEntry && foundEntry->m_type == SLANG_PATH_TYPE_FILE && foundEntry->m_canonicalPath == canonicalPath);
+ SLANG_ASSERT(
+ foundEntry && foundEntry->m_type == SLANG_PATH_TYPE_FILE &&
+ foundEntry->m_canonicalPath == canonicalPath);
*outEntry = foundEntry;
return SLANG_OK;
diff --git a/source/core/slang-memory-file-system.h b/source/core/slang-memory-file-system.h
index 321f7fe74..ebf6e239a 100644
--- a/source/core/slang-memory-file-system.h
+++ b/source/core/slang-memory-file-system.h
@@ -2,66 +2,81 @@
#define SLANG_CORE_MEMORY_FILE_SYSTEM_H
#include "slang-basic.h"
-
-#include "slang-com-ptr.h"
#include "slang-com-object.h"
+#include "slang-com-ptr.h"
namespace Slang
{
-/* MemoryFileSystem is an implementation of ISlangMutableFileSystem that stores file contents in 'blobs' (typically) in memory.
+/* MemoryFileSystem is an implementation of ISlangMutableFileSystem that stores file contents in
+'blobs' (typically) in memory.
-A derived class can change how the contents of the contents blob is interpretted (so for example the RiffFileSystem is implemented
-such that the Entry.m_contents is the files contents compressed).
+A derived class can change how the contents of the contents blob is interpretted (so for example the
+RiffFileSystem is implemented such that the Entry.m_contents is the files contents compressed).
-The implementation uses a map to store the file/directory based on their canonical path. This makes access relatively fast and simple -
-an access only requires a path being converted into a canonical path, and then a lookup. Whilst this makes typical access fast, it means
-doing an enumeration of a directory slower as it requires traversing all entries to find which are in the path.
+The implementation uses a map to store the file/directory based on their canonical path. This makes
+access relatively fast and simple - an access only requires a path being converted into a canonical
+path, and then a lookup. Whilst this makes typical access fast, it means doing an enumeration of a
+directory slower as it requires traversing all entries to find which are in the path.
-This is in contrast with an implementation that held items in directories 'objects'. In that scenario the path through the hierarchy
-would need to be traversed to find the item. Finding all of the items in a directory is very fast - it's all the items held
-in the the directory 'object'.
+This is in contrast with an implementation that held items in directories 'objects'. In that
+scenario the path through the hierarchy would need to be traversed to find the item. Finding all of
+the items in a directory is very fast - it's all the items held in the the directory 'object'.
TODO(JS):
-* We may want to make saveFile take a blob, or have a version that does. Doing so would allow the application to handle memory management
-around the blob.
+* We may want to make saveFile take a blob, or have a version that does. Doing so would allow the
+application to handle memory management around the blob.
*/
class MemoryFileSystem : public ISlangMutableFileSystem, public ComBaseObject
{
public:
-
- // ISlangUnknown
+ // ISlangUnknown
SLANG_COM_BASE_IUNKNOWN_ALL
// ISlangCastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// ISlangFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob)
+ SLANG_OVERRIDE;
// ISlangFileSystemExt
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getFileUniqueIdentity(const char* path, ISlangBlob** uniqueIdentityOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPathType(const char* path, SlangPathType* pathTypeOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getFileUniqueIdentity(const char* path, ISlangBlob** uniqueIdentityOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPathType(const char* path, SlangPathType* pathTypeOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL clearCache() SLANG_OVERRIDE {}
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE { return OSPathKind::None; }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE
+ {
+ return OSPathKind::None;
+ }
// ISlangModifyableFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL remove(const char* path) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL createDirectory(const char* path) SLANG_OVERRIDE;
- /// Ctor
+ /// Ctor
MemoryFileSystem();
protected:
-
struct Entry
{
- void reset()
+ void reset()
{
m_type = SLANG_PATH_TYPE_FILE;
m_canonicalPath = String();
@@ -100,10 +115,10 @@ protected:
SlangPathType m_type;
String m_canonicalPath;
- /// The size as seen on the file system. Might be different from the size of m_contents
+ /// The size as seen on the file system. Might be different from the size of m_contents
/// if it's actually being stored in some other representation (such as compressed)
- size_t m_uncompressedSizeInBytes;
- ComPtr<ISlangBlob> m_contents; ///< Can be compressed or not
+ size_t m_uncompressedSizeInBytes;
+ ComPtr<ISlangBlob> m_contents; ///< Can be compressed or not
};
void* getInterface(const Guid& guid);
@@ -111,28 +126,28 @@ protected:
Entry* _getEntryFromPath(const char* path, String* outPath = nullptr);
Entry* _getEntryFromCanonicalPath(const String& canonicalPath);
- /// Creates or returns a file entry for the given path.
- /// If created the entry is empty.
+ /// Creates or returns a file entry for the given path.
+ /// If created the entry is empty.
SlangResult _requireFile(const char* path, Entry** outEntry);
- /// Given the path returns the entry if it's a file, or returns an error
+ /// Given the path returns the entry if it's a file, or returns an error
SlangResult _loadFile(const char* path, Entry** outEntry);
- /// Given a path returns a canonical path.
- /// The canonical path must have *existing* parent paths.
+ /// Given a path returns a canonical path.
+ /// The canonical path must have *existing* parent paths.
SlangResult _getCanonicalWithExistingParent(const char* path, StringBuilder& canonicalPath);
- /// Given a path returns a canonical path.
+ /// Given a path returns a canonical path.
SlangResult _getCanonical(const char* path, StringBuilder& canonicalPath);
- /// Clear, ensures any backing memory is also freed
+ /// Clear, ensures any backing memory is also freed
void _clear();
// Maps canonical paths to an entries (which could be files or directories)
Dictionary<String, Entry> m_entries;
- Entry m_rootEntry;
+ Entry m_rootEntry;
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-name-value.cpp b/source/core/slang-name-value.cpp
index 5418043f5..9e1bf9ce1 100644
--- a/source/core/slang-name-value.cpp
+++ b/source/core/slang-name-value.cpp
@@ -2,12 +2,16 @@
#include "slang-name-value.h"
-#include "slang-string-util.h"
#include "slang-char-util.h"
+#include "slang-string-util.h"
-namespace Slang {
+namespace Slang
+{
-/* static */ValueInt NameValueUtil::findValue(const ConstArrayView<NameValue>& opts, const UnownedStringSlice& slice, ValueInt defaultValue)
+/* static */ ValueInt NameValueUtil::findValue(
+ const ConstArrayView<NameValue>& opts,
+ const UnownedStringSlice& slice,
+ ValueInt defaultValue)
{
for (const auto& opt : opts)
{
@@ -19,7 +23,10 @@ namespace Slang {
return defaultValue;
}
-/* static */ValueInt NameValueUtil::findValue(const ConstArrayView<NamesValue>& opts, const UnownedStringSlice& slice, ValueInt defaultValue)
+/* static */ ValueInt NameValueUtil::findValue(
+ const ConstArrayView<NamesValue>& opts,
+ const UnownedStringSlice& slice,
+ ValueInt defaultValue)
{
for (const auto& opt : opts)
{
@@ -33,7 +40,10 @@ namespace Slang {
return defaultValue;
}
-/* static */ValueInt NameValueUtil::findValue(const ConstArrayView<NamesDescriptionValue>& opts, const UnownedStringSlice& slice, ValueInt defaultValue)
+/* static */ ValueInt NameValueUtil::findValue(
+ const ConstArrayView<NamesDescriptionValue>& opts,
+ const UnownedStringSlice& slice,
+ ValueInt defaultValue)
{
for (const auto& opt : opts)
{
@@ -46,7 +56,10 @@ namespace Slang {
return defaultValue;
}
-/* static */ UnownedStringSlice NameValueUtil::findName(const ConstArrayView<NameValue>& opts, ValueInt value, const UnownedStringSlice& defaultName)
+/* static */ UnownedStringSlice NameValueUtil::findName(
+ const ConstArrayView<NameValue>& opts,
+ ValueInt value,
+ const UnownedStringSlice& defaultName)
{
for (const auto& opt : opts)
{
@@ -58,7 +71,10 @@ namespace Slang {
return defaultName;
}
-/* static */ UnownedStringSlice NameValueUtil::findName(const ConstArrayView<NamesValue>& opts, ValueInt value, const UnownedStringSlice& defaultName)
+/* static */ UnownedStringSlice NameValueUtil::findName(
+ const ConstArrayView<NamesValue>& opts,
+ ValueInt value,
+ const UnownedStringSlice& defaultName)
{
for (const auto& opt : opts)
{
@@ -72,7 +88,10 @@ namespace Slang {
return defaultName;
}
-/* static */ UnownedStringSlice NameValueUtil::findName(const ConstArrayView<NamesDescriptionValue>& opts, ValueInt value, const UnownedStringSlice& defaultName)
+/* static */ UnownedStringSlice NameValueUtil::findName(
+ const ConstArrayView<NamesDescriptionValue>& opts,
+ ValueInt value,
+ const UnownedStringSlice& defaultName)
{
for (const auto& opt : opts)
{
@@ -87,7 +106,10 @@ namespace Slang {
}
-/* static */UnownedStringSlice NameValueUtil::findDescription(const ConstArrayView<NamesDescriptionValue>& opts, ValueInt value, const UnownedStringSlice& defaultDescription)
+/* static */ UnownedStringSlice NameValueUtil::findDescription(
+ const ConstArrayView<NamesDescriptionValue>& opts,
+ ValueInt value,
+ const UnownedStringSlice& defaultDescription)
{
for (const auto& opt : opts)
{
@@ -100,7 +122,10 @@ namespace Slang {
return defaultDescription;
}
-/* static */ void NameValueUtil::appendNames(NameKind kind, const ConstArrayView<NameValue>& opts, List<UnownedStringSlice>& out)
+/* static */ void NameValueUtil::appendNames(
+ NameKind kind,
+ const ConstArrayView<NameValue>& opts,
+ List<UnownedStringSlice>& out)
{
SLANG_UNUSED(kind);
for (auto& opt : opts)
@@ -109,7 +134,10 @@ namespace Slang {
}
}
-static void _appendNames(NameValueUtil::NameKind kind, const char* names, List<UnownedStringSlice>& out)
+static void _appendNames(
+ NameValueUtil::NameKind kind,
+ const char* names,
+ List<UnownedStringSlice>& out)
{
if (kind == NameValueUtil::NameKind::All)
{
@@ -121,7 +149,10 @@ static void _appendNames(NameValueUtil::NameKind kind, const char* names, List<U
}
}
-/* static */ void NameValueUtil::appendNames(NameKind kind, const ConstArrayView<NamesValue>& opts, List<UnownedStringSlice>& out)
+/* static */ void NameValueUtil::appendNames(
+ NameKind kind,
+ const ConstArrayView<NamesValue>& opts,
+ List<UnownedStringSlice>& out)
{
for (auto& opt : opts)
{
@@ -129,7 +160,10 @@ static void _appendNames(NameValueUtil::NameKind kind, const char* names, List<U
}
}
-/* static */ void NameValueUtil::appendNames(NameKind kind, const ConstArrayView<NamesDescriptionValue>& opts, List<UnownedStringSlice>& out)
+/* static */ void NameValueUtil::appendNames(
+ NameKind kind,
+ const ConstArrayView<NamesDescriptionValue>& opts,
+ List<UnownedStringSlice>& out)
{
for (auto& opt : opts)
{
@@ -137,21 +171,27 @@ static void _appendNames(NameValueUtil::NameKind kind, const char* names, List<U
}
}
-/* static */ List<UnownedStringSlice> NameValueUtil::getNames(NameKind kind, const ConstArrayView<NameValue>& opts)
+/* static */ List<UnownedStringSlice> NameValueUtil::getNames(
+ NameKind kind,
+ const ConstArrayView<NameValue>& opts)
{
List<UnownedStringSlice> names;
appendNames(kind, opts, names);
return names;
}
-/* static */ List<UnownedStringSlice> NameValueUtil::getNames(NameKind kind, const ConstArrayView<NamesValue>& opts)
+/* static */ List<UnownedStringSlice> NameValueUtil::getNames(
+ NameKind kind,
+ const ConstArrayView<NamesValue>& opts)
{
List<UnownedStringSlice> names;
appendNames(kind, opts, names);
return names;
}
-/* static */ List<UnownedStringSlice> NameValueUtil::getNames(NameKind kind, const ConstArrayView<NamesDescriptionValue>& opts)
+/* static */ List<UnownedStringSlice> NameValueUtil::getNames(
+ NameKind kind,
+ const ConstArrayView<NamesDescriptionValue>& opts)
{
List<UnownedStringSlice> names;
appendNames(kind, opts, names);
@@ -159,5 +199,3 @@ static void _appendNames(NameValueUtil::NameKind kind, const char* names, List<U
}
} // namespace Slang
-
-
diff --git a/source/core/slang-name-value.h b/source/core/slang-name-value.h
index a50e149a8..5062f2c45 100644
--- a/source/core/slang-name-value.h
+++ b/source/core/slang-name-value.h
@@ -1,9 +1,8 @@
#ifndef SLANG_CORE_NAME_VALUE_H
#define SLANG_CORE_NAME_VALUE_H
-#include "slang-basic.h"
-
#include "slang-array-view.h"
+#include "slang-basic.h"
namespace Slang
{
@@ -20,57 +19,107 @@ struct NameValue
struct NamesValue
{
ValueInt value;
- const char* names; ///< Can hold comma delimited list of names
-
+ const char* names; ///< Can hold comma delimited list of names
};
struct NamesDescriptionValue
{
ValueInt value;
- const char* names; ///< Can hold comma delimited list of names
- const char* description; ///< Optional description, can hold null ptr or empty string if not defined
+ const char* names; ///< Can hold comma delimited list of names
+ const char*
+ description; ///< Optional description, can hold null ptr or empty string if not defined
};
struct NameValueUtil
{
enum class NameKind
{
- First, ///< Only the first name if there is more than one
- All, ///< All valid associated names
+ First, ///< Only the first name if there is more than one
+ All, ///< All valid associated names
};
- /// Use the default type to infer the actual type desired
- template <typename T>
- static T findValue(const ConstArrayView<NameValue>& opts, const UnownedStringSlice& slice, T defaultValue) { return (T)findValue(opts, slice, ValueInt(defaultValue)); }
- template <typename T>
- static T findValue(const ConstArrayView<NamesValue>& opts, const UnownedStringSlice& slice, T defaultValue) { return (T)findValue(opts, slice, ValueInt(defaultValue)); }
- template <typename T>
- static T findValue(const ConstArrayView<NamesDescriptionValue>& opts, const UnownedStringSlice& slice, T defaultValue) { return (T)findValue(opts, slice, ValueInt(defaultValue)); }
+ /// Use the default type to infer the actual type desired
+ template<typename T>
+ static T findValue(
+ const ConstArrayView<NameValue>& opts,
+ const UnownedStringSlice& slice,
+ T defaultValue)
+ {
+ return (T)findValue(opts, slice, ValueInt(defaultValue));
+ }
+ template<typename T>
+ static T findValue(
+ const ConstArrayView<NamesValue>& opts,
+ const UnownedStringSlice& slice,
+ T defaultValue)
+ {
+ return (T)findValue(opts, slice, ValueInt(defaultValue));
+ }
+ template<typename T>
+ static T findValue(
+ const ConstArrayView<NamesDescriptionValue>& opts,
+ const UnownedStringSlice& slice,
+ T defaultValue)
+ {
+ return (T)findValue(opts, slice, ValueInt(defaultValue));
+ }
- /// Given a slice finds the associated value. If no entry is found, defaultValue is returned
- static ValueInt findValue(const ConstArrayView<NameValue>& opts, const UnownedStringSlice& slice, ValueInt defaultValue = -1);
- static ValueInt findValue(const ConstArrayView<NamesValue>& opts, const UnownedStringSlice& slice, ValueInt defaultValue = -1);
- static ValueInt findValue(const ConstArrayView<NamesDescriptionValue>& opts, const UnownedStringSlice& slice, ValueInt defaultValue = -1);
+ /// Given a slice finds the associated value. If no entry is found, defaultValue is returned
+ static ValueInt findValue(
+ const ConstArrayView<NameValue>& opts,
+ const UnownedStringSlice& slice,
+ ValueInt defaultValue = -1);
+ static ValueInt findValue(
+ const ConstArrayView<NamesValue>& opts,
+ const UnownedStringSlice& slice,
+ ValueInt defaultValue = -1);
+ static ValueInt findValue(
+ const ConstArrayView<NamesDescriptionValue>& opts,
+ const UnownedStringSlice& slice,
+ ValueInt defaultValue = -1);
- /// Given a value find the name. If there are multiple names, returns the first name
- static UnownedStringSlice findName(const ConstArrayView<NameValue>& opts, ValueInt value, const UnownedStringSlice& defaultName = UnownedStringSlice());
- static UnownedStringSlice findName(const ConstArrayView<NamesValue>& opts, ValueInt value, const UnownedStringSlice& defaultName = UnownedStringSlice());
- static UnownedStringSlice findName(const ConstArrayView<NamesDescriptionValue>& opts, ValueInt value, const UnownedStringSlice& defaultName = UnownedStringSlice());
+ /// Given a value find the name. If there are multiple names, returns the first name
+ static UnownedStringSlice findName(
+ const ConstArrayView<NameValue>& opts,
+ ValueInt value,
+ const UnownedStringSlice& defaultName = UnownedStringSlice());
+ static UnownedStringSlice findName(
+ const ConstArrayView<NamesValue>& opts,
+ ValueInt value,
+ const UnownedStringSlice& defaultName = UnownedStringSlice());
+ static UnownedStringSlice findName(
+ const ConstArrayView<NamesDescriptionValue>& opts,
+ ValueInt value,
+ const UnownedStringSlice& defaultName = UnownedStringSlice());
- /// Append all the names from opts to out
- static void appendNames(NameKind kind, const ConstArrayView<NameValue>& opts, List<UnownedStringSlice>& out);
- static void appendNames(NameKind kind, const ConstArrayView<NamesValue>& opts, List<UnownedStringSlice>& out);
- static void appendNames(NameKind kind, const ConstArrayView<NamesDescriptionValue>& opts, List<UnownedStringSlice>& out);
+ /// Append all the names from opts to out
+ static void appendNames(
+ NameKind kind,
+ const ConstArrayView<NameValue>& opts,
+ List<UnownedStringSlice>& out);
+ static void appendNames(
+ NameKind kind,
+ const ConstArrayView<NamesValue>& opts,
+ List<UnownedStringSlice>& out);
+ static void appendNames(
+ NameKind kind,
+ const ConstArrayView<NamesDescriptionValue>& opts,
+ List<UnownedStringSlice>& out);
- /// Return the list of all valid names
+ /// Return the list of all valid names
static List<UnownedStringSlice> getNames(NameKind kind, const ConstArrayView<NameValue>& opts);
static List<UnownedStringSlice> getNames(NameKind kind, const ConstArrayView<NamesValue>& opts);
- static List<UnownedStringSlice> getNames(NameKind kind, const ConstArrayView<NamesDescriptionValue>& opts);
-
- /// Get the description
- static UnownedStringSlice findDescription(const ConstArrayView<NamesDescriptionValue>& opts, ValueInt value, const UnownedStringSlice& defaultDescription = UnownedStringSlice());
+ static List<UnownedStringSlice> getNames(
+ NameKind kind,
+ const ConstArrayView<NamesDescriptionValue>& opts);
+
+ /// Get the description
+ static UnownedStringSlice findDescription(
+ const ConstArrayView<NamesDescriptionValue>& opts,
+ ValueInt value,
+ const UnownedStringSlice& defaultDescription = UnownedStringSlice());
};
} // namespace Slang
-#endif
+#endif
diff --git a/source/core/slang-offset-container.cpp b/source/core/slang-offset-container.cpp
index 75852c990..c216b704d 100644
--- a/source/core/slang-offset-container.cpp
+++ b/source/core/slang-offset-container.cpp
@@ -1,7 +1,8 @@
// slang-offset-container.cpp
#include "slang-offset-container.h"
-namespace Slang {
+namespace Slang
+{
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! OffsetString !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -22,14 +23,14 @@ size_t OffsetString::calcEncodedSize(size_t size, uint8_t encode[kMaxSizeEncodeS
num++;
}
- // It might be one byte past the front, if its < 0x100 but greater than kSizeBase
+ // It might be one byte past the front, if its < 0x100 but greater than kSizeBase
SLANG_ASSERT(num >= 1);
encode[0] = uint8_t(kSizeBase + num);
return num + 1;
}
-/* static */const char* OffsetString::decodeSize(const char* in, size_t& outSize)
+/* static */ const char* OffsetString::decodeSize(const char* in, size_t& outSize)
{
const uint8_t* cur = (const uint8_t*)in;
if (*cur <= kSizeBase)
@@ -41,27 +42,28 @@ size_t OffsetString::calcEncodedSize(size_t size, uint8_t encode[kMaxSizeEncodeS
int numBytes = *cur - kSizeBase;
switch (numBytes)
{
- case 1:
+ case 1:
{
outSize = cur[1];
return in + 2;
}
- case 2:
+ case 2:
{
outSize = cur[1] | (uint32_t(cur[2]) << 8);
return in + 3;
}
- case 3:
+ case 3:
{
outSize = cur[1] | (uint32_t(cur[2]) << 8) | (uint32_t(cur[3]) << 16);
return in + 4;
}
- case 4:
+ case 4:
{
- outSize = cur[1] | (uint32_t(cur[2]) << 8) | (uint32_t(cur[3]) << 16) | (uint32_t(cur[4]) << 24);
+ outSize = cur[1] | (uint32_t(cur[2]) << 8) | (uint32_t(cur[3]) << 16) |
+ (uint32_t(cur[4]) << 24);
return in + 5;
}
- default:
+ default:
{
outSize = 0;
return nullptr;
@@ -69,7 +71,7 @@ size_t OffsetString::calcEncodedSize(size_t size, uint8_t encode[kMaxSizeEncodeS
}
}
-/* static */size_t OffsetString::calcAllocationSize(size_t stringSize)
+/* static */ size_t OffsetString::calcAllocationSize(size_t stringSize)
{
uint8_t encode[kMaxSizeEncodeSize];
size_t encodeSize = calcEncodedSize(stringSize, encode);
@@ -77,7 +79,7 @@ size_t OffsetString::calcEncodedSize(size_t size, uint8_t encode[kMaxSizeEncodeS
return encodeSize + stringSize + 1;
}
-/* static */size_t OffsetString::calcAllocationSize(const UnownedStringSlice& slice)
+/* static */ size_t OffsetString::calcAllocationSize(const UnownedStringSlice& slice)
{
return calcAllocationSize(slice.getLength());
}
@@ -95,14 +97,15 @@ const char* OffsetString::getCstr() const
return getSlice().begin();
}
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! OffsetContainer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! OffsetContainer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
OffsetContainer::OffsetContainer()
{
m_capacity = 0;
m_data = nullptr;
- // We need to allocate some of the first bytes 0 can be used for nullptr.
+ // We need to allocate some of the first bytes 0 can be used for nullptr.
allocateAndZero(kStartOffset, 1);
}
@@ -174,7 +177,7 @@ Offset32Ptr<OffsetString> OffsetContainer::newString(const UnownedStringSlice& s
size_t allocSize = headSize + stringSize + 1;
uint8_t* bytes = (uint8_t*)allocate(allocSize);
- ::memcpy(bytes, head, headSize);
+ ::memcpy(bytes, head, headSize);
::memcpy(bytes + headSize, slice.begin(), stringSize);
// 0 terminate
diff --git a/source/core/slang-offset-container.h b/source/core/slang-offset-container.h
index 95c3a6589..4e6920bed 100644
--- a/source/core/slang-offset-container.h
+++ b/source/core/slang-offset-container.h
@@ -4,54 +4,62 @@
#include "slang-basic.h"
-namespace Slang {
+namespace Slang
+{
/*
-The purpose of OffsetContainer and related types is to provide a mechanism to easily serialize offset structures.
+The purpose of OffsetContainer and related types is to provide a mechanism to easily serialize
+offset structures.
-The root idea here is the "offset pointer". A typical pointer in a language like C/C++ holds the absolute address
-in the current address space of the thing that is being pointed to. This introduces a problem, as when data is
-serialized in the contents will very likely be be placed at different addresses - meaning any absolute pointer
-will point to the wrong place. There is also a related issue around pointer sizes - on some targets they are 32 bits
-and on others 64 bits.
+The root idea here is the "offset pointer". A typical pointer in a language like C/C++ holds the
+absolute address in the current address space of the thing that is being pointed to. This introduces
+a problem, as when data is serialized in the contents will very likely be be placed at different
+addresses - meaning any absolute pointer will point to the wrong place. There is also a related
+issue around pointer sizes - on some targets they are 32 bits and on others 64 bits.
-An offset pointer means a pointer that points to something 'offset' to some base address. The OffsetPtr uses a 32 bit
-offset from the pointers location in memory. This means such a pointer can address a 4Gb address space.
+An offset pointer means a pointer that points to something 'offset' to some base address. The
+OffsetPtr uses a 32 bit offset from the pointers location in memory. This means such a pointer can
+address a 4Gb address space.
-Special care is needed when using offset pointers - both when constructing structures that contain them, reading
-them and in general usage.
+Special care is needed when using offset pointers - both when constructing structures that contain
+them, reading them and in general usage.
-For simplicity here we store all offset pointers within a single contiguous allocation. This allocation is
-typically managed by the OffsetContainer for writing. When reading a MemoryOffsetBase can be used.
+For simplicity here we store all offset pointers within a single contiguous allocation. This
+allocation is typically managed by the OffsetContainer for writing. When reading a MemoryOffsetBase
+can be used.
-An issue around using offset pointers, is that we cannot directly access it's contents, because it's just an
-offset to some base address. Thus to access the thing being pointed to we need to turn the offset pointer back into
-a 'raw' pointer. This is achieved via using the asRaw methods on the OffsetBase. For a convenience operator[] can also
-be used, and this is typically the preferred mechanism.
+An issue around using offset pointers, is that we cannot directly access it's contents, because it's
+just an offset to some base address. Thus to access the thing being pointed to we need to turn the
+offset pointer back into a 'raw' pointer. This is achieved via using the asRaw methods on the
+OffsetBase. For a convenience operator[] can also be used, and this is typically the preferred
+mechanism.
-NOTE! That the evaluation order of a function calls parameters is undefined in C++. That whilst it might appear doing
+NOTE! That the evaluation order of a function calls parameters is undefined in C++. That whilst it
+might appear doing
```
base[thing] = container.newObject<Thing>();
```
-will evaluate the construction of newObject *before* the assignment, if you look at the assignment as being a function call
-(as it is when it is overloaded), then base[thing] might be evaluated *before* newObject, and if it is then the result
-could be wrong if the newObject needed to reallocate. Therefore when allocation is involved, a new (or any allocation backed
-function call from the OffsetContainer) should always place a result in a local variable. Then assign as in
+will evaluate the construction of newObject *before* the assignment, if you look at the assignment
+as being a function call (as it is when it is overloaded), then base[thing] might be evaluated
+*before* newObject, and if it is then the result could be wrong if the newObject needed to
+reallocate. Therefore when allocation is involved, a new (or any allocation backed function call
+from the OffsetContainer) should always place a result in a local variable. Then assign as in
```
auto anotherThing = container.newObject<Thing>();
-base[thing] = anotherThing;
+base[thing] = anotherThing;
```
-When creating structures - unless you know the allocated space (in the OffsetContainer or some other piece of memory)
-is larger than required, then special care is needed, because when a new larger piece of memory is allocated to hold
-everything, raw pointers pointers will likely be invalidated. When reading there is typically no need to move
-the base address, so raw pointers remain valid through out. When doing writing if a call is made to something that
-allocates memory on the OffsetContainer - any raw pointer should be assumed invalid.
+When creating structures - unless you know the allocated space (in the OffsetContainer or some other
+piece of memory) is larger than required, then special care is needed, because when a new larger
+piece of memory is allocated to hold everything, raw pointers pointers will likely be invalidated.
+When reading there is typically no need to move the base address, so raw pointers remain valid
+through out. When doing writing if a call is made to something that allocates memory on the
+OffsetContainer - any raw pointer should be assumed invalid.
-For example
+For example
```
@@ -83,7 +91,7 @@ void func()
// Or more perhaps slightly more conveniently []
auto rawThing = base[thing];
-
+
// We can write and read things via the Safe32Ptr
rawThing->value = 10;
const int value = rawThing->value;
@@ -93,18 +101,18 @@ void func()
// Now lets write to it
{
- // We can have raw pointer (or reference) to a thing but we need to be *careful* if we allocate
- Thing* rawThing = base[thing];
- // We are okay here, nothing between getting the raw pointer and the write allocated/newed anything on the OffsetContainer
- rawThing->value = 20;
+ // We can have raw pointer (or reference) to a thing but we need to be *careful* if we
+allocate Thing* rawThing = base[thing];
+ // We are okay here, nothing between getting the raw pointer and the write allocated/newed
+anything on the OffsetContainer rawThing->value = 20;
- // Lets set up name
+ // Lets set up name
Offset32Ptr<OffsetString> text = offsetContainer.newString("Hello World!");
- // BAD! The rawThing point could now be invalid because the call to newString may have had to allocate more memory
- rawThing->text = text;
+ // BAD! The rawThing point could now be invalid because the call to newString may have had
+to allocate more memory rawThing->text = text;
- // This is okay
+ // This is okay
base[thing]->text = text;
// Or we can update rawThing such that is up to date
@@ -112,10 +120,12 @@ void func()
// So now this is okay again
rawThing->text = text;
- // BAD! we don't know the evaluation order here, if the lhs is evaluate before the rhs, then it could write to the wrong area of memory.
- base[thing]->text = offsetContainer.newString("Hello World again!");
+ // BAD! we don't know the evaluation order here, if the lhs is evaluate before the rhs, then
+it could write to the wrong area of memory. base[thing]->text = offsetContainer.newString("Hello
+World again!");
- // So where there is allocation, and assignment to something that in held in offset ptr use a local for the allocation as in
+ // So where there is allocation, and assignment to something that in held in offset ptr use
+a local for the allocation as in
{
auto text = offsetContainer.newString("Hello World again!");
base[thing]->text = text;
@@ -128,23 +138,27 @@ void func()
enum
{
- kNull32Offset = 0,
- kStartOffset = uint32_t(sizeof(uint64_t)), ///< The offset to the first contained thing
+ kNull32Offset = 0,
+ kStartOffset = uint32_t(sizeof(uint64_t)), ///< The offset to the first contained thing
};
-template <typename T>
+template<typename T>
class Offset32Ref;
/* A pointer to items held in OffsetContainer (or OffsetBase relative) that remains correct even if
the memory inside OffsetContainer moves.
*/
-template <typename T>
+template<typename T>
class Offset32Ptr
{
public:
typedef Offset32Ptr ThisType;
- const ThisType& operator=(const ThisType& rhs) { m_offset = rhs.m_offset; return *this; }
+ const ThisType& operator=(const ThisType& rhs)
+ {
+ m_offset = rhs.m_offset;
+ return *this;
+ }
bool operator==(const ThisType& rhs) const { return m_offset == rhs.m_offset; }
bool operator!=(const ThisType& rhs) const { return m_offset != rhs.m_offset; }
@@ -157,55 +171,99 @@ public:
Offset32Ref<T> operator*();
- ThisType& operator++() { m_offset += uint32_t(sizeof(T)); return *this; }
- ThisType operator++(int) { const auto offset = m_offset; m_offset += uint32_t(sizeof(T)); return ThisType(offset); }
+ ThisType& operator++()
+ {
+ m_offset += uint32_t(sizeof(T));
+ return *this;
+ }
+ ThisType operator++(int)
+ {
+ const auto offset = m_offset;
+ m_offset += uint32_t(sizeof(T));
+ return ThisType(offset);
+ }
- ThisType& operator--() { m_offset -= sizeof(T); return *this; }
- ThisType operator--(int) { const auto offset = m_offset; m_offset -= uint32_t(sizeof(T)); return ThisType(offset); }
+ ThisType& operator--()
+ {
+ m_offset -= sizeof(T);
+ return *this;
+ }
+ ThisType operator--(int)
+ {
+ const auto offset = m_offset;
+ m_offset -= uint32_t(sizeof(T));
+ return ThisType(offset);
+ }
- friend ThisType operator+(const ThisType& a, Index b) { return ThisType(a.m_offset + uint32_t(sizeof(T) * b)); }
- friend ThisType operator+(Index a, const ThisType& b) { return ThisType(b.m_offset + uint32_t(sizeof(T) * a)); }
+ friend ThisType operator+(const ThisType& a, Index b)
+ {
+ return ThisType(a.m_offset + uint32_t(sizeof(T) * b));
+ }
+ friend ThisType operator+(Index a, const ThisType& b)
+ {
+ return ThisType(b.m_offset + uint32_t(sizeof(T) * a));
+ }
bool isNull() const { return m_offset == kNull32Offset; }
void setNull() { m_offset = kNull32Offset; }
- Offset32Ptr():m_offset(kNull32Offset) {}
- Offset32Ptr(const ThisType& rhs): m_offset(rhs.m_offset) {}
- explicit Offset32Ptr(uint32_t offset): m_offset(offset) {}
+ Offset32Ptr()
+ : m_offset(kNull32Offset)
+ {
+ }
+ Offset32Ptr(const ThisType& rhs)
+ : m_offset(rhs.m_offset)
+ {
+ }
+ explicit Offset32Ptr(uint32_t offset)
+ : m_offset(offset)
+ {
+ }
uint32_t m_offset;
};
-/* A reference to items held in OffsetContainer (or OffsetBase relative) that remains correct even if
-the memory inside OffsetContainer moves.
+/* A reference to items held in OffsetContainer (or OffsetBase relative) that remains correct even
+if the memory inside OffsetContainer moves.
*/
-template <typename T>
+template<typename T>
class Offset32Ref
{
public:
typedef Offset32Ref ThisType;
- const ThisType& operator=(const ThisType& rhs) { m_offset = rhs.m_offset; return *this; }
+ const ThisType& operator=(const ThisType& rhs)
+ {
+ m_offset = rhs.m_offset;
+ return *this;
+ }
Offset32Ptr<T> operator&() { return Offset32Ptr<T>(m_offset); }
- Offset32Ref(const ThisType& rhs) : m_offset(rhs.m_offset) {}
- explicit Offset32Ref(uint32_t offset) : m_offset(offset) { SLANG_ASSERT(offset != kNull32Offset); }
+ Offset32Ref(const ThisType& rhs)
+ : m_offset(rhs.m_offset)
+ {
+ }
+ explicit Offset32Ref(uint32_t offset)
+ : m_offset(offset)
+ {
+ SLANG_ASSERT(offset != kNull32Offset);
+ }
uint32_t m_offset;
};
// ---------------------------------------------------------------------------
-template <typename T>
+template<typename T>
SLANG_FORCE_INLINE Offset32Ref<T> Offset32Ptr<T>::operator*()
{
return Offset32Ref<T>(m_offset);
}
-/* Much like Offset32Ptr this is an array but whose memory is stored inside the OffsetContainer. This means elements types
-must be 'offset types'. */
-template <typename T>
+/* Much like Offset32Ptr this is an array but whose memory is stored inside the OffsetContainer.
+This means elements types must be 'offset types'. */
+template<typename T>
class Offset32Array
{
public:
@@ -217,20 +275,34 @@ public:
Index getCount() const { return Index(m_count); }
- Offset32Ref<const T> operator[](Index i) const { SLANG_ASSERT(i >= 0 && uint32_t(i) < m_count); return Offset32Ref<const T>((m_data + i).m_offset); }
- Offset32Ref<T> operator[](Index i) { SLANG_ASSERT(i >= 0 && uint32_t(i) < m_count); return Offset32Ref<T>((m_data + i).m_offset); }
+ Offset32Ref<const T> operator[](Index i) const
+ {
+ SLANG_ASSERT(i >= 0 && uint32_t(i) < m_count);
+ return Offset32Ref<const T>((m_data + i).m_offset);
+ }
+ Offset32Ref<T> operator[](Index i)
+ {
+ SLANG_ASSERT(i >= 0 && uint32_t(i) < m_count);
+ return Offset32Ref<T>((m_data + i).m_offset);
+ }
- Offset32Array(Offset32Ptr<T> data, uint32_t count) :m_data(data), m_count(count) {}
+ Offset32Array(Offset32Ptr<T> data, uint32_t count)
+ : m_data(data), m_count(count)
+ {
+ }
- Offset32Array() :m_count(0) {}
+ Offset32Array()
+ : m_count(0)
+ {
+ }
Offset32Ptr<T> m_data;
uint32_t m_count;
};
-/** OffsetString is used for storing strings within a OffsetContainer. Strings are stored with the initial byte indicating the size
-of the string. Note that all offset strings are stored with a terminating zero, and that the terminating zero is *NOT* included in
-the encoded size. */
+/** OffsetString is used for storing strings within a OffsetContainer. Strings are stored with the
+initial byte indicating the size of the string. Note that all offset strings are stored with a
+terminating zero, and that the terminating zero is *NOT* included in the encoded size. */
struct OffsetString
{
enum
@@ -239,51 +311,75 @@ struct OffsetString
kMaxSizeEncodeSize = 5,
};
- /// Get contents as a slice
+ /// Get contents as a slice
UnownedStringSlice getSlice() const;
- /// Get null terminated string
+ /// Get null terminated string
const char* getCstr() const;
- /// Decode the size. Returns the start of the string text, and outSize holds the size (NOT including terminating 0)
+ /// Decode the size. Returns the start of the string text, and outSize holds the size (NOT
+ /// including terminating 0)
static const char* decodeSize(const char* in, size_t& outSize);
- /// Returns the amount of bytes used, end encoding in 'encode'
+ /// Returns the amount of bytes used, end encoding in 'encode'
static size_t calcEncodedSize(size_t size, uint8_t encode[kMaxSizeEncodeSize]);
- /// Calculate the total size needed to store the string *including* terminating 0
+ /// Calculate the total size needed to store the string *including* terminating 0
static size_t calcAllocationSize(const UnownedStringSlice& slice);
- /// Calculate the total size needed to store string. Size should be passed *without* terminating 0
+ /// Calculate the total size needed to store string. Size should be passed *without* terminating
+ /// 0
static size_t calcAllocationSize(size_t size);
char m_sizeThenContents[1];
};
-/* A type that is used to hold the base address of the contiguous memory that holds either Offset32Ptr and related types>
-*/
+/* A type that is used to hold the base address of the contiguous memory that holds either
+ * Offset32Ptr and related types>
+ */
class OffsetBase
{
public:
typedef OffsetBase ThisType;
- /// Turn an offset into a raw regular pointer or reference
- template <typename T>
- T* asRaw(const Offset32Ptr<T>& ptr) { return (T*)_getRaw(ptr.m_offset); }
- template <typename T>
- T& asRaw(const Offset32Ref<T>& ref) { return *(T*)_getRaw(ref.m_offset); }
-
- /// A more terse way to get a raw pointer/reference. Using the [] operator can be seen as 'indexing' to access the
- /// object the offset relates to. Unlike 'indices' that are typically used with [] offsets are generally not contiguous.
- template <typename T>
- T* operator[](const Offset32Ptr<T>& ptr) { return (T*)_getRaw(ptr.m_offset); }
- template <typename T>
- T& operator[](const Offset32Ref<T>& ref) { return *(T*)_getRaw(ref.m_offset); }
-
- template <typename T>
- Offset32Ptr<T> asPtr(T* ptr) { return Offset32Ptr<T>(getOffset(ptr)); }
- /// Note the use of ptr when setting up a reference here - it's needed because a ref does not have to be backed by a pointer.
- /// And commonly is not when the const& and the thing referenced can be held in a word.
- template <typename T>
- Offset32Ref<T> asRef(T* ptr) { SLANG_ASSERT(ptr); return Offset32Ref<T>(getOffset(ptr)); }
+ /// Turn an offset into a raw regular pointer or reference
+ template<typename T>
+ T* asRaw(const Offset32Ptr<T>& ptr)
+ {
+ return (T*)_getRaw(ptr.m_offset);
+ }
+ template<typename T>
+ T& asRaw(const Offset32Ref<T>& ref)
+ {
+ return *(T*)_getRaw(ref.m_offset);
+ }
+
+ /// A more terse way to get a raw pointer/reference. Using the [] operator can be seen as
+ /// 'indexing' to access the object the offset relates to. Unlike 'indices' that are typically
+ /// used with [] offsets are generally not contiguous.
+ template<typename T>
+ T* operator[](const Offset32Ptr<T>& ptr)
+ {
+ return (T*)_getRaw(ptr.m_offset);
+ }
+ template<typename T>
+ T& operator[](const Offset32Ref<T>& ref)
+ {
+ return *(T*)_getRaw(ref.m_offset);
+ }
+
+ template<typename T>
+ Offset32Ptr<T> asPtr(T* ptr)
+ {
+ return Offset32Ptr<T>(getOffset(ptr));
+ }
+ /// Note the use of ptr when setting up a reference here - it's needed because a ref does not
+ /// have to be backed by a pointer. And commonly is not when the const& and the thing referenced
+ /// can be held in a word.
+ template<typename T>
+ Offset32Ref<T> asRef(T* ptr)
+ {
+ SLANG_ASSERT(ptr);
+ return Offset32Ref<T>(getOffset(ptr));
+ }
uint32_t getOffset(const void* ptr)
{
@@ -296,30 +392,31 @@ public:
return uint32_t(diff);
}
- /// Get the contained data
+ /// Get the contained data
SLANG_FORCE_INLINE uint8_t* getData() { return m_data; }
- /// Return the last used byte of the data
+ /// Return the last used byte of the data
SLANG_FORCE_INLINE size_t getDataCount() const { return m_dataSize; }
- /// Get the first allocated thing. Typically the root of the structure contained
- void* getFirst() { return (m_dataSize < kStartOffset) ? nullptr : (m_data + kStartOffset); }
-
- /// Get a raw pointer from the offset
- uint8_t* _getRaw(uint32_t offset) { return (offset == kNull32Offset) ? nullptr : (m_data + offset); }
+ /// Get the first allocated thing. Typically the root of the structure contained
+ void* getFirst() { return (m_dataSize < kStartOffset) ? nullptr : (m_data + kStartOffset); }
- OffsetBase():
- m_data(nullptr),
- m_dataSize(0)
+ /// Get a raw pointer from the offset
+ uint8_t* _getRaw(uint32_t offset)
{
+ return (offset == kNull32Offset) ? nullptr : (m_data + offset);
}
+ OffsetBase()
+ : m_data(nullptr), m_dataSize(0)
+ {
+ }
uint8_t* m_data;
size_t m_dataSize;
protected:
- /// We want protected, because we don't want copies to be made of OffsetBase by default!
+ /// We want protected, because we don't want copies to be made of OffsetBase by default!
OffsetBase(const ThisType& rhs) = default;
ThisType& operator=(const ThisType& rhs) = default;
};
@@ -334,17 +431,18 @@ public:
}
};
-/* OffsetContainer is a type designed to manage the construction structures around 'offset types'. In particular it allows
-for construction of offset structures where their total encoded size is not known at the outset.
+/* OffsetContainer is a type designed to manage the construction structures around 'offset types'.
+In particular it allows for construction of offset structures where their total encoded size is not
+known at the outset.
-The main mechanism to make this work is via the use of OffsetXXX types, which when constructed from the OffsetContainer will
-maintain valid values, even if the underlying backing memories location is changed.
+The main mechanism to make this work is via the use of OffsetXXX types, which when constructed from
+the OffsetContainer will maintain valid values, even if the underlying backing memories location is
+changed.
*/
class OffsetContainer : public OffsetBase
{
public:
-
- template <typename T>
+ template<typename T>
Offset32Ptr<T> newObject()
{
void* data = allocate(sizeof(T), SLANG_ALIGN_OF(T));
@@ -352,7 +450,7 @@ public:
return Offset32Ptr<T>(getOffset(data));
}
- template <typename T>
+ template<typename T>
Offset32Array<T> newArray(size_t size)
{
if (size == 0)
@@ -367,7 +465,7 @@ public:
return Offset32Array<T>(Offset32Ptr<T>(getOffset(data)), uint32_t(size));
}
- /// Get the base - which is needed for turning offsets into things
+ /// Get the base - which is needed for turning offsets into things
OffsetBase& asBase() { return *this; }
/// Allocate without alignment (effectively 1)
@@ -380,7 +478,7 @@ public:
Offset32Ptr<OffsetString> newString(const UnownedStringSlice& slice);
Offset32Ptr<OffsetString> newString(const char* contents);
- /// Ctor
+ /// Ctor
OffsetContainer();
~OffsetContainer();
diff --git a/source/core/slang-performance-profiler.cpp b/source/core/slang-performance-profiler.cpp
index b272c9e17..9bc532680 100644
--- a/source/core/slang-performance-profiler.cpp
+++ b/source/core/slang-performance-profiler.cpp
@@ -1,122 +1,120 @@
#include "slang-performance-profiler.h"
+
#include "slang-dictionary.h"
namespace Slang
{
- class PerformanceProfilerImpl : public PerformanceProfiler
- {
- public:
- OrderedDictionary<const char*, FuncProfileInfo> data;
+class PerformanceProfilerImpl : public PerformanceProfiler
+{
+public:
+ OrderedDictionary<const char*, FuncProfileInfo> data;
- virtual FuncProfileContext enterFunction(const char* funcName) override
- {
- auto entry = data.tryGetValue(funcName);
- if (!entry)
- {
- data.add(funcName, FuncProfileInfo());
- entry = data.tryGetValue(funcName);
- }
- entry->invocationCount++;
- FuncProfileContext ctx;
- ctx.funcName = funcName;
- ctx.startTime = std::chrono::high_resolution_clock::now();
- return ctx;
- }
- virtual void exitFunction(FuncProfileContext ctx) override
- {
- auto endTime = std::chrono::high_resolution_clock::now();
- auto duration = endTime - ctx.startTime;
- auto entry = data.tryGetValue(ctx.funcName);
- entry->duration += duration;
- }
- virtual void getResult(StringBuilder& out) override
- {
- char buffer[512];
- for (const auto& func : data)
- {
- memset(buffer, 0, sizeof(buffer));
- snprintf(buffer, sizeof(buffer), "[*] %30s", func.key);
- out << buffer << " \t";
- auto milliseconds = std::chrono::duration_cast< std::chrono::milliseconds >(func.value.duration);
- out << func.value.invocationCount << " \t" << static_cast<uint64_t>(milliseconds.count()) << "ms\n";
- }
- }
- virtual void clear() override
+ virtual FuncProfileContext enterFunction(const char* funcName) override
+ {
+ auto entry = data.tryGetValue(funcName);
+ if (!entry)
{
- data.clear();
+ data.add(funcName, FuncProfileInfo());
+ entry = data.tryGetValue(funcName);
}
- virtual void dispose() override
+ entry->invocationCount++;
+ FuncProfileContext ctx;
+ ctx.funcName = funcName;
+ ctx.startTime = std::chrono::high_resolution_clock::now();
+ return ctx;
+ }
+ virtual void exitFunction(FuncProfileContext ctx) override
+ {
+ auto endTime = std::chrono::high_resolution_clock::now();
+ auto duration = endTime - ctx.startTime;
+ auto entry = data.tryGetValue(ctx.funcName);
+ entry->duration += duration;
+ }
+ virtual void getResult(StringBuilder& out) override
+ {
+ char buffer[512];
+ for (const auto& func : data)
{
- data = decltype(data)();
+ memset(buffer, 0, sizeof(buffer));
+ snprintf(buffer, sizeof(buffer), "[*] %30s", func.key);
+ out << buffer << " \t";
+ auto milliseconds =
+ std::chrono::duration_cast<std::chrono::milliseconds>(func.value.duration);
+ out << func.value.invocationCount << " \t"
+ << static_cast<uint64_t>(milliseconds.count()) << "ms\n";
}
- };
-
- PerformanceProfiler* Slang::PerformanceProfiler::getProfiler()
- {
- thread_local static PerformanceProfilerImpl profiler = PerformanceProfilerImpl();
- return &profiler;
}
+ virtual void clear() override { data.clear(); }
+ virtual void dispose() override { data = decltype(data)(); }
+};
- SlangProfiler::SlangProfiler(PerformanceProfiler* profiler)
- {
- PerformanceProfilerImpl* profilerImpl = static_cast<PerformanceProfilerImpl*>(profiler);
- size_t entryCount = profilerImpl->data.getCount();
+PerformanceProfiler* Slang::PerformanceProfiler::getProfiler()
+{
+ thread_local static PerformanceProfilerImpl profiler = PerformanceProfilerImpl();
+ return &profiler;
+}
+
+SlangProfiler::SlangProfiler(PerformanceProfiler* profiler)
+{
+ PerformanceProfilerImpl* profilerImpl = static_cast<PerformanceProfilerImpl*>(profiler);
+ size_t entryCount = profilerImpl->data.getCount();
+
+ m_profilEntries.reserve(entryCount);
- m_profilEntries.reserve(entryCount);
+ int index = 0;
+ for (auto func : profilerImpl->data)
+ {
+ ProfileInfo profileEntry{};
+ size_t strSize = std::min(sizeof(profileEntry.funcName) - 1, strlen(func.key));
- int index = 0;
- for (auto func : profilerImpl->data)
+ if (strSize > 0)
{
- ProfileInfo profileEntry {};
- size_t strSize = std::min(sizeof(profileEntry.funcName) - 1, strlen(func.key));
-
- if (strSize > 0)
- {
- memcpy(profileEntry.funcName, func.key, strSize);
- }
- profileEntry.invocationCount = func.value.invocationCount;
- profileEntry.duration = func.value.duration;
-
- m_profilEntries.insert(index, profileEntry);
- index++;
+ memcpy(profileEntry.funcName, func.key, strSize);
}
- }
+ profileEntry.invocationCount = func.value.invocationCount;
+ profileEntry.duration = func.value.duration;
- ISlangUnknown* SlangProfiler::getInterface(const Guid& guid)
- {
- if(guid == SlangProfiler::getTypeGuid())
- return static_cast<ISlangUnknown*>(this);
- else
- return nullptr;
+ m_profilEntries.insert(index, profileEntry);
+ index++;
}
+}
- size_t SlangProfiler::getEntryCount()
- {
- return m_profilEntries.getCount();
- }
+ISlangUnknown* SlangProfiler::getInterface(const Guid& guid)
+{
+ if (guid == SlangProfiler::getTypeGuid())
+ return static_cast<ISlangUnknown*>(this);
+ else
+ return nullptr;
+}
- const char* SlangProfiler::getEntryName(uint32_t index)
- {
- if (index >= (uint32_t)m_profilEntries.getCount())
- return nullptr;
+size_t SlangProfiler::getEntryCount()
+{
+ return m_profilEntries.getCount();
+}
- return m_profilEntries[index].funcName;
- }
+const char* SlangProfiler::getEntryName(uint32_t index)
+{
+ if (index >= (uint32_t)m_profilEntries.getCount())
+ return nullptr;
- long SlangProfiler::getEntryTimeMS(uint32_t index)
- {
- if (index >= (uint32_t)m_profilEntries.getCount())
- return 0;
+ return m_profilEntries[index].funcName;
+}
- auto milliseconds = std::chrono::duration_cast< std::chrono::milliseconds >(m_profilEntries[index].duration);
- return (long)milliseconds.count();
- }
+long SlangProfiler::getEntryTimeMS(uint32_t index)
+{
+ if (index >= (uint32_t)m_profilEntries.getCount())
+ return 0;
- uint32_t SlangProfiler::getEntryInvocationTimes(uint32_t index)
- {
- if (index >= (uint32_t)m_profilEntries.getCount())
- return 0;
+ auto milliseconds =
+ std::chrono::duration_cast<std::chrono::milliseconds>(m_profilEntries[index].duration);
+ return (long)milliseconds.count();
+}
- return m_profilEntries[index].invocationCount;
- }
+uint32_t SlangProfiler::getEntryInvocationTimes(uint32_t index)
+{
+ if (index >= (uint32_t)m_profilEntries.getCount())
+ return 0;
+
+ return m_profilEntries[index].invocationCount;
}
+} // namespace Slang
diff --git a/source/core/slang-performance-profiler.h b/source/core/slang-performance-profiler.h
index 9895793c4..40ace4e6d 100644
--- a/source/core/slang-performance-profiler.h
+++ b/source/core/slang-performance-profiler.h
@@ -1,11 +1,12 @@
#ifndef SLANG_CORE_PERFORMANCE_PROFILER_H
#define SLANG_CORE_PERFORMANCE_PROFILER_H
+#include "../core/slang-list.h"
+#include "slang-com-helper.h"
#include "slang-string.h"
+
#include <chrono>
#include <vector>
-#include "slang-com-helper.h"
-#include "../core/slang-list.h"
namespace Slang
{
@@ -30,6 +31,7 @@ public:
virtual void getResult(StringBuilder& out) = 0;
virtual void clear() = 0;
virtual void dispose() = 0;
+
public:
static PerformanceProfiler* getProfiler();
};
@@ -47,7 +49,7 @@ struct PerformanceProfilerFuncRAIIContext
}
};
-struct SlangProfiler: public ISlangProfiler, public RefObject
+struct SlangProfiler : public ISlangProfiler, public RefObject
{
public:
SLANG_REF_OBJECT_IUNKNOWN_ALL
@@ -57,20 +59,21 @@ public:
int invocationCount = 0;
std::chrono::nanoseconds duration = std::chrono::nanoseconds::zero();
};
- SlangProfiler(PerformanceProfiler * profiler);
+ SlangProfiler(PerformanceProfiler* profiler);
ISlangUnknown* getInterface(const Guid& guid);
virtual SLANG_NO_THROW size_t SLANG_MCALL getEntryCount() override;
virtual SLANG_NO_THROW const char* SLANG_MCALL getEntryName(uint32_t index) override;
virtual SLANG_NO_THROW long SLANG_MCALL getEntryTimeMS(uint32_t index) override;
virtual SLANG_NO_THROW uint32_t SLANG_MCALL getEntryInvocationTimes(uint32_t index) override;
+
private:
List<ProfileInfo> m_profilEntries;
};
-#define SLANG_PROFILE PerformanceProfilerFuncRAIIContext _profileContext(__func__)
+#define SLANG_PROFILE PerformanceProfilerFuncRAIIContext _profileContext(__func__)
#define SLANG_PROFILE_SECTION(s) PerformanceProfilerFuncRAIIContext _profileContext##s(#s)
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-persistent-cache.cpp b/source/core/slang-persistent-cache.cpp
index 2b4113e16..ca3400231 100644
--- a/source/core/slang-persistent-cache.cpp
+++ b/source/core/slang-persistent-cache.cpp
@@ -1,9 +1,9 @@
#include "slang-persistent-cache.h"
+#include "../core/slang-blob.h"
#include "../core/slang-io.h"
#include "../core/slang-stream.h"
#include "../core/slang-string-util.h"
-#include "../core/slang-blob.h"
namespace Slang
{
@@ -25,9 +25,7 @@ PersistentCache::PersistentCache(const Desc& desc)
initialize();
}
-PersistentCache::~PersistentCache()
-{
-}
+PersistentCache::~PersistentCache() {}
SlangResult PersistentCache::clear()
{
@@ -46,13 +44,14 @@ SlangResult PersistentCache::clear()
const String& lockFileName;
Visitor(const String& directory, const String& lockFileName)
- : directory(directory)
- , lockFileName(lockFileName)
- {}
+ : directory(directory), lockFileName(lockFileName)
+ {
+ }
void accept(Path::Type type, const UnownedStringSlice& fileName) SLANG_OVERRIDE
{
- String fullPath = Path::simplify(directory + "/" + fileName);;
+ String fullPath = Path::simplify(directory + "/" + fileName);
+ ;
if (type == Path::Type::File && lockFileName != fullPath)
{
Path::remove(fullPath);
@@ -106,7 +105,8 @@ SlangResult PersistentCache::readEntry(const Key& key, ISlangBlob** outData)
}
// Find the entry.
- Index entryIndex = cacheIndex.findFirstIndex([&key] (const CacheEntry& entry) { return entry.key == key; });
+ Index entryIndex =
+ cacheIndex.findFirstIndex([&key](const CacheEntry& entry) { return entry.key == key; });
if (entryIndex == -1)
{
return SLANG_E_NOT_FOUND;
@@ -171,7 +171,8 @@ SlangResult PersistentCache::writeEntry(const Key& key, ISlangBlob* data)
// Write the cache entry.
String entryFileName = getEntryFileName(key);
- SLANG_RETURN_ON_FAIL(File::writeAllBytes(entryFileName, data->getBufferPointer(), data->getBufferSize()));
+ SLANG_RETURN_ON_FAIL(
+ File::writeAllBytes(entryFileName, data->getBufferPointer(), data->getBufferSize()));
// Update the index.
if (m_maxEntryCount > 0 && cacheIndex.getCount() >= m_maxEntryCount)
@@ -179,12 +180,12 @@ SlangResult PersistentCache::writeEntry(const Key& key, ISlangBlob* data)
// Replace oldest entry.
SLANG_ASSERT(oldestEntryIndex >= 0);
File::remove(getEntryFileName(cacheIndex[oldestEntryIndex].key));
- cacheIndex[oldestEntryIndex] = CacheEntry{ key, 0 };
+ cacheIndex[oldestEntryIndex] = CacheEntry{key, 0};
}
else
{
// Add new entry.
- cacheIndex.add(CacheEntry{ key, 0 });
+ cacheIndex.add(CacheEntry{key, 0});
}
// Write the cache index.
@@ -265,7 +266,7 @@ SlangResult PersistentCache::readIndex(const String& fileName, CacheIndex& outIn
outIndex.setCount(header.count);
SLANG_RETURN_ON_FAIL(fs.readExactly(outIndex.getBuffer(), header.count * sizeof(CacheEntry)));
-
+
return SLANG_OK;
}
@@ -286,4 +287,4 @@ SlangResult PersistentCache::writeIndex(const String& fileName, const CacheIndex
return SLANG_OK;
}
-}
+} // namespace Slang
diff --git a/source/core/slang-persistent-cache.h b/source/core/slang-persistent-cache.h
index e7d02b861..9425bf7a2 100644
--- a/source/core/slang-persistent-cache.h
+++ b/source/core/slang-persistent-cache.h
@@ -18,7 +18,7 @@ class PersistentCache : public RefObject
{
public:
struct Desc
- {
+ {
// The root directory for the cache.
const char* directory = nullptr;
// The maximum number of entries stored in the cache. By default, there is no limit.
@@ -49,7 +49,7 @@ public:
/// Read an entry from the cache.
/// Returns SLANG_OK if successful, SLANG_E_NOT_FOUND if the entry is not in the cache.
SlangResult readEntry(const Key& key, ISlangBlob** outData);
-
+
/// Write an entry to the cache.
/// Returns SLANG_OK if successful.
SlangResult writeEntry(const Key& key, ISlangBlob* data);
@@ -88,4 +88,4 @@ private:
friend struct PersistentCacheTest;
};
-}
+} // namespace Slang
diff --git a/source/core/slang-platform.cpp b/source/core/slang-platform.cpp
index e84f9095f..ea8a2f4a5 100644
--- a/source/core/slang-platform.cpp
+++ b/source/core/slang-platform.cpp
@@ -8,24 +8,27 @@
#include "slang-io.h"
#ifdef _WIN32
- #include <windows.h>
+#include <windows.h>
#else
- #include "slang-string.h"
- #include <dlfcn.h>
+#include "slang-string.h"
+
+#include <dlfcn.h>
#endif
namespace Slang
{
- // SharedLibrary
+// SharedLibrary
-/* static */SlangResult SharedLibrary::load(const char* path, SharedLibrary::Handle& handleOut)
+/* static */ SlangResult SharedLibrary::load(const char* path, SharedLibrary::Handle& handleOut)
{
StringBuilder builder;
calcPlatformPath(UnownedStringSlice(path), builder);
return loadWithPlatformPath(builder.begin(), handleOut);
}
-/* static */void SharedLibrary::calcPlatformPath(const UnownedStringSlice& path, StringBuilder& outPath)
+/* static */ void SharedLibrary::calcPlatformPath(
+ const UnownedStringSlice& path,
+ StringBuilder& outPath)
{
// Work out the shared library name
String parent = Path::getParentDirectory(path);
@@ -37,15 +40,18 @@ namespace Slang
StringBuilder platformFileNameBuilder;
SharedLibrary::appendPlatformFileName(filename.getUnownedSlice(), platformFileNameBuilder);
- Path::combineIntoBuilder(parent.getUnownedSlice(), platformFileNameBuilder.getUnownedSlice(), outPath);
+ Path::combineIntoBuilder(
+ parent.getUnownedSlice(),
+ platformFileNameBuilder.getUnownedSlice(),
+ outPath);
}
else if (filename.getLength() > 0)
- {
+ {
appendPlatformFileName(filename.getUnownedSlice(), outPath);
}
}
-/* static */String SharedLibrary::calcPlatformPath(const UnownedStringSlice& path)
+/* static */ String SharedLibrary::calcPlatformPath(const UnownedStringSlice& path)
{
StringBuilder builder;
calcPlatformPath(path, builder);
@@ -62,7 +68,7 @@ SLANG_COMPILE_TIME_ASSERT(E_NOTIMPL == SLANG_E_NOT_IMPLEMENTED);
SLANG_COMPILE_TIME_ASSERT(E_INVALIDARG == SLANG_E_INVALID_ARG);
SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
-/* static */SlangResult PlatformUtil::getInstancePath(StringBuilder& out)
+/* static */ SlangResult PlatformUtil::getInstancePath(StringBuilder& out)
{
wchar_t path[_MAX_PATH];
::GetModuleFileName(::GetModuleHandle(NULL), path, SLANG_COUNT_OF(path));
@@ -75,12 +81,13 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
return out.getLength() > 0 ? SLANG_OK : SLANG_FAIL;
}
-/* static */SlangResult PlatformUtil::appendResult(SlangResult res, StringBuilder& builderOut)
+/* static */ SlangResult PlatformUtil::appendResult(SlangResult res, StringBuilder& builderOut)
{
if (SLANG_FAILED(res) && res != SLANG_FAIL)
{
LPWSTR buffer = nullptr;
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
nullptr,
res,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
@@ -100,7 +107,9 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
return SLANG_FAIL;
}
-/* static */SlangResult SharedLibrary::loadWithPlatformPath(char const* platformFileName, SharedLibrary::Handle& handleOut)
+/* static */ SlangResult SharedLibrary::loadWithPlatformPath(
+ char const* platformFileName,
+ SharedLibrary::Handle& handleOut)
{
handleOut = nullptr;
if (!platformFileName || strlen(platformFileName) == 0)
@@ -117,19 +126,19 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
const DWORD lastError = GetLastError();
switch (lastError)
{
- case ERROR_MOD_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_FILE_NOT_FOUND:
+ case ERROR_MOD_NOT_FOUND:
+ case ERROR_PATH_NOT_FOUND:
+ case ERROR_FILE_NOT_FOUND:
{
return SLANG_E_NOT_FOUND;
}
- case ERROR_INVALID_ACCESS:
- case ERROR_ACCESS_DENIED:
- case ERROR_INVALID_DATA:
+ case ERROR_INVALID_ACCESS:
+ case ERROR_ACCESS_DENIED:
+ case ERROR_INVALID_DATA:
{
return SLANG_E_CANNOT_OPEN;
}
- default: break;
+ default: break;
}
// Turn to Result, if not one of the well known errors
return HRESULT_FROM_WIN32(lastError);
@@ -138,7 +147,7 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
return SLANG_OK;
}
-/* static */void SharedLibrary::unload(Handle handle)
+/* static */ void SharedLibrary::unload(Handle handle)
{
SLANG_ASSERT(handle);
::FreeLibrary((HMODULE)handle);
@@ -150,7 +159,9 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
return GetProcAddress((HMODULE)handle, name);
}
-/* static */void SharedLibrary::appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst)
+/* static */ void SharedLibrary::appendPlatformFileName(
+ const UnownedStringSlice& name,
+ StringBuilder& dst)
{
dst.append(name);
dst.append(".dll");
@@ -158,19 +169,23 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
#else // _WIN32
-/* static */SlangResult PlatformUtil::getInstancePath([[maybe_unused]] StringBuilder& out)
+/* static */ SlangResult PlatformUtil::getInstancePath([[maybe_unused]] StringBuilder& out)
{
// On non Windows it's typically hard to get the instance path, so we'll say not implemented.
// The meaning is also somewhat more ambiguous - is it the exe or the shared library path?
return SLANG_E_NOT_IMPLEMENTED;
}
-/* static */SlangResult PlatformUtil::appendResult([[maybe_unused]] SlangResult res, [[maybe_unused]] StringBuilder& builderOut)
+/* static */ SlangResult PlatformUtil::appendResult(
+ [[maybe_unused]] SlangResult res,
+ [[maybe_unused]] StringBuilder& builderOut)
{
return SLANG_E_NOT_IMPLEMENTED;
}
-/* static */SlangResult SharedLibrary::loadWithPlatformPath(char const* platformFileName, Handle& handleOut)
+/* static */ SlangResult SharedLibrary::loadWithPlatformPath(
+ char const* platformFileName,
+ Handle& handleOut)
{
handleOut = nullptr;
// Work around
@@ -180,9 +195,9 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
// closed
const auto unclosableLibNames = {"libdxcompiler", "libdxvk_d3d11", "libdxvk_dxgi"};
bool isUnclosable = false;
- for(auto n : unclosableLibNames)
+ for (auto n : unclosableLibNames)
{
- if(strncmp(platformFileName, n, strlen(n)) == 0)
+ if (strncmp(platformFileName, n, strlen(n)) == 0)
{
isUnclosable = true;
break;
@@ -191,7 +206,7 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
if (strlen(platformFileName) == 0)
platformFileName = nullptr;
const auto mode = RTLD_NOW | RTLD_GLOBAL | (isUnclosable ? RTLD_NODELETE : 0);
- void *h = dlopen(platformFileName, mode);
+ void* h = dlopen(platformFileName, mode);
if (!h)
{
#if 0
@@ -202,23 +217,25 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
}
#endif
return SLANG_FAIL;
- }
+ }
handleOut = (Handle)h;
return SLANG_OK;
}
-/* static */void SharedLibrary::unload(Handle handle)
-{
+/* static */ void SharedLibrary::unload(Handle handle)
+{
SLANG_ASSERT(handle);
- dlclose(handle);
+ dlclose(handle);
}
-/* static */void* SharedLibrary::findSymbolAddressByName(Handle handle, char const* name)
+/* static */ void* SharedLibrary::findSymbolAddressByName(Handle handle, char const* name)
{
- return dlsym((void*)handle, name);
+ return dlsym((void*)handle, name);
}
-/* static */void SharedLibrary::appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst)
+/* static */ void SharedLibrary::appendPlatformFileName(
+ const UnownedStringSlice& name,
+ StringBuilder& dst)
{
#if __CYGWIN__
dst.append(name);
@@ -242,7 +259,9 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
#endif // _WIN32
-/* static */SlangResult PlatformUtil::getEnvironmentVariable(const UnownedStringSlice& name, StringBuilder& out)
+/* static */ SlangResult PlatformUtil::getEnvironmentVariable(
+ const UnownedStringSlice& name,
+ StringBuilder& out)
{
const char* value = getenv(String(name).getBuffer());
if (value)
@@ -253,7 +272,7 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
return SLANG_E_NOT_FOUND;
}
-/* static */PlatformKind PlatformUtil::getPlatformKind()
+/* static */ PlatformKind PlatformUtil::getPlatformKind()
{
#if SLANG_WINRT
return PlatformKind::WinRT;
@@ -286,22 +305,22 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
#endif
}
-static const PlatformFlags s_familyFlags[int(PlatformFamily::CountOf)] =
-{
- 0, // Unknown
- PlatformFlag::WinRT | PlatformFlag::Win32 | PlatformFlag::Win64, // Windows
- PlatformFlag::WinRT | PlatformFlag::Win32 | PlatformFlag::Win64 | PlatformFlag::X360 | PlatformFlag::XBoxOne, // Microsoft
- PlatformFlag::Linux | PlatformFlag::Android, // Linux
- PlatformFlag::IOS | PlatformFlag::OSX, // Apple
- PlatformFlag::Linux | PlatformFlag::Android | PlatformFlag::IOS | PlatformFlag::OSX, // Unix
+static const PlatformFlags s_familyFlags[int(PlatformFamily::CountOf)] = {
+ 0, // Unknown
+ PlatformFlag::WinRT | PlatformFlag::Win32 | PlatformFlag::Win64, // Windows
+ PlatformFlag::WinRT | PlatformFlag::Win32 | PlatformFlag::Win64 | PlatformFlag::X360 |
+ PlatformFlag::XBoxOne, // Microsoft
+ PlatformFlag::Linux | PlatformFlag::Android, // Linux
+ PlatformFlag::IOS | PlatformFlag::OSX, // Apple
+ PlatformFlag::Linux | PlatformFlag::Android | PlatformFlag::IOS | PlatformFlag::OSX, // Unix
};
-/* static */PlatformFlags PlatformUtil::getPlatformFlags(PlatformFamily family)
+/* static */ PlatformFlags PlatformUtil::getPlatformFlags(PlatformFamily family)
{
return s_familyFlags[int(family)];
}
-/* static */SlangResult PlatformUtil::outputDebugMessage([[maybe_unused]] const char* text)
+/* static */ SlangResult PlatformUtil::outputDebugMessage([[maybe_unused]] const char* text)
{
#ifdef _WIN32
OutputDebugStringA(text);
@@ -311,4 +330,4 @@ static const PlatformFlags s_familyFlags[int(PlatformFamily::CountOf)] =
#endif
}
-}
+} // namespace Slang
diff --git a/source/core/slang-platform.h b/source/core/slang-platform.h
index 81bae88d6..0b97aca6d 100644
--- a/source/core/slang-platform.h
+++ b/source/core/slang-platform.h
@@ -7,150 +7,157 @@
namespace Slang
{
- enum class PlatformKind : uint8_t
+enum class PlatformKind : uint8_t
+{
+ Unknown,
+ WinRT,
+ XBoxOne,
+ Win64,
+ Win32,
+ X360,
+ Android,
+ Linux,
+ IOS,
+ OSX,
+ PS3,
+ PS4,
+ PSP2,
+ WIIU,
+ CountOf,
+};
+
+typedef uint32_t PlatformFlags;
+struct PlatformFlag
+{
+ enum Enum
{
- Unknown,
- WinRT,
- XBoxOne,
- Win64,
- Win32,
- X360,
- Android,
- Linux,
- IOS,
- OSX,
- PS3,
- PS4,
- PSP2,
- WIIU,
- CountOf,
+ Unknown = 1 << int(PlatformKind::Unknown),
+ WinRT = 1 << int(PlatformKind::WinRT),
+ XBoxOne = 1 << int(PlatformKind::XBoxOne),
+ Win64 = 1 << int(PlatformKind::Win64),
+ Win32 = 1 << int(PlatformKind::Win32),
+ X360 = 1 << int(PlatformKind::X360),
+ Android = 1 << int(PlatformKind::Android),
+ Linux = 1 << int(PlatformKind::Linux),
+ IOS = 1 << int(PlatformKind::IOS),
+ OSX = 1 << int(PlatformKind::OSX),
+ PS3 = 1 << int(PlatformKind::PS3),
+ PS4 = 1 << int(PlatformKind::PS4),
+ PSP2 = 1 << int(PlatformKind::PSP2),
+ WIIU = 1 << int(PlatformKind::WIIU),
};
+};
- typedef uint32_t PlatformFlags;
- struct PlatformFlag
- {
- enum Enum
- {
- Unknown = 1 << int(PlatformKind::Unknown),
- WinRT = 1 << int(PlatformKind::WinRT),
- XBoxOne = 1 << int(PlatformKind::XBoxOne),
- Win64 = 1 << int(PlatformKind::Win64),
- Win32 = 1 << int(PlatformKind::Win32),
- X360 = 1 << int(PlatformKind::X360),
- Android = 1 << int(PlatformKind::Android),
- Linux = 1 << int(PlatformKind::Linux),
- IOS = 1 << int(PlatformKind::IOS),
- OSX = 1 << int(PlatformKind::OSX),
- PS3 = 1 << int(PlatformKind::PS3),
- PS4 = 1 << int(PlatformKind::PS4),
- PSP2 = 1 << int(PlatformKind::PSP2),
- WIIU = 1 << int(PlatformKind::WIIU),
- };
- };
+enum class PlatformFamily : uint8_t
+{
+ Unknown,
+ Windows,
+ Microsoft,
+ Linux,
+ Apple,
+ Unix,
+ CountOf,
+};
+
+// Interface for working with shared libraries
+// in a platform-independent fashion.
+struct SharedLibrary
+{
+ typedef struct SharedLibraryImpl* Handle;
+
+ typedef void (*FuncPtr)(void);
+
+ /// Load via an unadorned path/filename.
+ ///
+ /// The unadorned path here means without a path without any platform specific filename
+ /// elements. This typically means no extension and no prefix. On windows this means without the
+ /// '.dll' extension. On linux this means without the 'lib' prefix and '.so' extension. To load
+ /// with a platform specific filename use the 'loadWithPlatformFilename' API Most platforms have
+ /// a built in mechanism to search for shared libraries, such that shared libraries are often
+ /// just passed by filename.
+ ///
+ /// @param the unadorned filename/path
+ /// @return Returns a non null handle for the shared library on success. nullptr indicated
+ /// failure
+ static SlangResult load(const char* path, Handle& handleOut);
+
+ /// Attempt to load a shared library for
+ /// the current platform. Returns null handle on failure
+ /// The platform specific filename can be generated from a call to appendPlatformFileName
+ ///
+ /// @param platform the platform specific file name/ or path
+ /// @return Returns a non null handle for the shared library on success. nullptr indicated
+ /// failure
+ static SlangResult loadWithPlatformPath(char const* platformPath, Handle& handleOut);
+
+ /// Unload the library that was returned from load as handle
+ /// @param The valid handle returned from load
+ static void unload(Handle handle);
+
+ /// Given a shared library handle and a name, return the associated object
+ /// Return nullptr if object is not found
+ /// @param The shared library handle as returned by loadPlatformLibrary
+ static void* findSymbolAddressByName(Handle handle, char const* name);
+
+ /// Append to the end of dst, the name, with any platform specific additions
+ /// The input name should be unadorned with any 'lib' prefix or extension
+ static void appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst);
+
+ /// Given a path, calculate that path with the filename replaced with the platform filename
+ /// (using appendPlatformFilename)
+ static String calcPlatformPath(const UnownedStringSlice& path);
+ static void calcPlatformPath(const UnownedStringSlice& path, StringBuilder& outBuilder);
+
+
+private:
+ /// Not constructible!
+ SharedLibrary();
+};
+
+struct PlatformUtil
+{
+ /// Appends a text interpretation of a result (as defined by supporting OS)
+ /// @param res Result to produce a string for
+ /// @param builderOut Append the string produced to builderOut
+ /// @return SLANG_OK if string is found and appended. Fail otherwise. SLANG_E_NOT_IMPLEMENTED if
+ /// there is no impl for this platform.
+ static SlangResult appendResult(SlangResult res, StringBuilder& builderOut);
- enum class PlatformFamily : uint8_t
- {
- Unknown,
- Windows,
- Microsoft,
- Linux,
- Apple,
- Unix,
- CountOf,
- };
+ /// Get the platform kind as determined at compile time
+ static PlatformKind getPlatformKind();
- // Interface for working with shared libraries
- // in a platform-independent fashion.
- struct SharedLibrary
- {
- typedef struct SharedLibraryImpl* Handle;
-
- typedef void(*FuncPtr)(void);
-
- /// Load via an unadorned path/filename.
- ///
- /// The unadorned path here means without a path without any platform specific filename elements.
- /// This typically means no extension and no prefix.
- /// On windows this means without the '.dll' extension.
- /// On linux this means without the 'lib' prefix and '.so' extension.
- /// To load with a platform specific filename use the 'loadWithPlatformFilename' API
- /// Most platforms have a built in mechanism to search for shared libraries, such that
- /// shared libraries are often just passed by filename.
- ///
- /// @param the unadorned filename/path
- /// @return Returns a non null handle for the shared library on success. nullptr indicated failure
- static SlangResult load(const char* path, Handle& handleOut);
-
- /// Attempt to load a shared library for
- /// the current platform. Returns null handle on failure
- /// The platform specific filename can be generated from a call to appendPlatformFileName
- ///
- /// @param platform the platform specific file name/ or path
- /// @return Returns a non null handle for the shared library on success. nullptr indicated failure
- static SlangResult loadWithPlatformPath(char const* platformPath, Handle& handleOut);
-
- /// Unload the library that was returned from load as handle
- /// @param The valid handle returned from load
- static void unload(Handle handle);
-
- /// Given a shared library handle and a name, return the associated object
- /// Return nullptr if object is not found
- /// @param The shared library handle as returned by loadPlatformLibrary
- static void* findSymbolAddressByName(Handle handle, char const* name);
-
- /// Append to the end of dst, the name, with any platform specific additions
- /// The input name should be unadorned with any 'lib' prefix or extension
- static void appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst);
-
- /// Given a path, calculate that path with the filename replaced with the platform filename (using appendPlatformFilename)
- static String calcPlatformPath(const UnownedStringSlice& path);
- static void calcPlatformPath(const UnownedStringSlice& path, StringBuilder& outBuilder);
-
-
- private:
- /// Not constructible!
- SharedLibrary();
- };
+ /// Get the platforms that make up a family
+ static PlatformFlags getPlatformFlags(PlatformFamily family);
- struct PlatformUtil
+ /// True if the kind is part of the family
+ static bool isFamily(PlatformFamily family, PlatformKind kind)
{
- /// Appends a text interpretation of a result (as defined by supporting OS)
- /// @param res Result to produce a string for
- /// @param builderOut Append the string produced to builderOut
- /// @return SLANG_OK if string is found and appended. Fail otherwise. SLANG_E_NOT_IMPLEMENTED if there is no impl for this platform.
- static SlangResult appendResult(SlangResult res, StringBuilder& builderOut);
-
- /// Get the platform kind as determined at compile time
- static PlatformKind getPlatformKind();
-
- /// Get the platforms that make up a family
- static PlatformFlags getPlatformFlags(PlatformFamily family);
-
- /// True if the kind is part of the family
- static bool isFamily(PlatformFamily family, PlatformKind kind) { return (getPlatformFlags(family) & (PlatformFlags(1) << int(kind))) != 0; }
-
- /// Given an environment name returns the set system variable.
- /// Will return SLANG_E_NOT_FOUND if the variable is not set
- static SlangResult getEnvironmentVariable(const UnownedStringSlice& name, StringBuilder& out);
-
- /// Get the path to this instance (the path to the dll/executable/shared library the call is in)
- /// NOTE! This is not supported on all platforms, and will return SLANG_E_NOT_IMPLEMENTED in that scenario
- static SlangResult getInstancePath(StringBuilder& out);
-
- /// Outputs message to a debug stream. Not all platforms support
- /// this feature.
- ///
- /// @param text Text to be displayed in 'debugger output'
- /// @return SLANG_E_NOT_AVAILABLE if not on this platform, and potentially other errors
- static SlangResult outputDebugMessage(const char* text);
- };
+ return (getPlatformFlags(family) & (PlatformFlags(1) << int(kind))) != 0;
+ }
+
+ /// Given an environment name returns the set system variable.
+ /// Will return SLANG_E_NOT_FOUND if the variable is not set
+ static SlangResult getEnvironmentVariable(const UnownedStringSlice& name, StringBuilder& out);
+
+ /// Get the path to this instance (the path to the dll/executable/shared library the call is in)
+ /// NOTE! This is not supported on all platforms, and will return SLANG_E_NOT_IMPLEMENTED in
+ /// that scenario
+ static SlangResult getInstancePath(StringBuilder& out);
+
+ /// Outputs message to a debug stream. Not all platforms support
+ /// this feature.
+ ///
+ /// @param text Text to be displayed in 'debugger output'
+ /// @return SLANG_E_NOT_AVAILABLE if not on this platform, and potentially other errors
+ static SlangResult outputDebugMessage(const char* text);
+};
#ifndef _MSC_VER
- #define _fileno fileno
- #define _isatty isatty
- #define _setmode setmode
- #define _O_BINARY O_BINARY
+#define _fileno fileno
+#define _isatty isatty
+#define _setmode setmode
+#define _O_BINARY O_BINARY
#endif
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-process-util.cpp b/source/core/slang-process-util.cpp
index 47484156d..62cc4b1dc 100644
--- a/source/core/slang-process-util.cpp
+++ b/source/core/slang-process-util.cpp
@@ -2,15 +2,17 @@
#include "slang-process-util.h"
-#include "slang-string.h"
+#include "slang-com-helper.h"
#include "slang-string-escape-util.h"
#include "slang-string-util.h"
+#include "slang-string.h"
-#include "slang-com-helper.h"
-
-namespace Slang {
+namespace Slang
+{
-/* static */SlangResult ProcessUtil::execute(const CommandLine& commandLine, ExecuteResult& outExecuteResult)
+/* static */ SlangResult ProcessUtil::execute(
+ const CommandLine& commandLine,
+ ExecuteResult& outExecuteResult)
{
RefPtr<Process> process;
SLANG_RETURN_ON_FAIL(Process::create(commandLine, 0, process));
@@ -27,11 +29,15 @@ static Index _getCount(List<Byte>* buf)
static String _getText(const ConstArrayView<Byte>& bytes)
{
StringBuilder buf;
- StringUtil::appendStandardLines(UnownedStringSlice((const char*)bytes.begin(), (const char*)bytes.end()), buf);
+ StringUtil::appendStandardLines(
+ UnownedStringSlice((const char*)bytes.begin(), (const char*)bytes.end()),
+ buf);
return buf.produceString();
}
-/* static */SlangResult ProcessUtil::readUntilTermination(Process* process, ExecuteResult& outExecuteResult)
+/* static */ SlangResult ProcessUtil::readUntilTermination(
+ Process* process,
+ ExecuteResult& outExecuteResult)
{
List<Byte> stdOut;
List<Byte> stdError;
@@ -47,7 +53,10 @@ static String _getText(const ConstArrayView<Byte>& bytes)
return SLANG_OK;
}
-/* static */SlangResult ProcessUtil::readUntilTermination(Process* process, List<Byte>* outStdOut, List<Byte>* outStdError)
+/* static */ SlangResult ProcessUtil::readUntilTermination(
+ Process* process,
+ List<Byte>* outStdOut,
+ List<Byte>* outStdError)
{
Stream* stdOutStream = process->getStream(StdStreamType::Out);
Stream* stdErrorStream = process->getStream(StdStreamType::ErrorOut);
@@ -70,7 +79,7 @@ static String _getText(const ConstArrayView<Byte>& bytes)
}
// Read anything remaining
- for(;;)
+ for (;;)
{
const auto preCount = _getCount(outStdOut) + _getCount(outStdError);
StreamUtil::readOrDiscard(stdOutStream, 0, outStdOut);
diff --git a/source/core/slang-process-util.h b/source/core/slang-process-util.h
index 14ca208f8..25cf0aca3 100644
--- a/source/core/slang-process-util.h
+++ b/source/core/slang-process-util.h
@@ -4,7 +4,8 @@
#include "slang-process.h"
-namespace Slang {
+namespace Slang
+{
struct ExecuteResult
{
@@ -24,17 +25,20 @@ struct ExecuteResult
struct ProcessUtil
{
- /// Execute the command line
+ /// Execute the command line
static SlangResult execute(const CommandLine& commandLine, ExecuteResult& outExecuteResult);
- /// Read from read from streams until process terminates.
- /// Passing nullptr for a stream, will just discard what's in the stream
- static SlangResult readUntilTermination(Process* process, List<Byte>* outStdOut, List<Byte>* stdError);
+ /// Read from read from streams until process terminates.
+ /// Passing nullptr for a stream, will just discard what's in the stream
+ static SlangResult readUntilTermination(
+ Process* process,
+ List<Byte>* outStdOut,
+ List<Byte>* stdError);
- /// Read streams from process.
+ /// Read streams from process.
static SlangResult readUntilTermination(Process* process, ExecuteResult& outExecuteResult);
};
-}
+} // namespace Slang
#endif // SLANG_PROCESS_UTIL_H
diff --git a/source/core/slang-process.h b/source/core/slang-process.h
index c36064ac3..002e2d5e1 100644
--- a/source/core/slang-process.h
+++ b/source/core/slang-process.h
@@ -2,16 +2,15 @@
#ifndef SLANG_PROCESS_H
#define SLANG_PROCESS_H
-#include "slang-string.h"
+#include "slang-command-line.h"
+#include "slang-io.h"
#include "slang-list.h"
#include "slang-stream.h"
-#include "slang-io.h"
-
#include "slang-string-escape-util.h"
+#include "slang-string.h"
-#include "slang-command-line.h"
-
-namespace Slang {
+namespace Slang
+{
class Process : public RefObject
{
@@ -27,59 +26,64 @@ public:
};
};
- /// Get the stream for the type
+ /// Get the stream for the type
Stream* getStream(StdStreamType type) const { return m_streams[Index(type)]; }
- /// Get the value returned from the process when it exited/returned.
- int32_t getReturnValue() const { return m_returnValue; }
+ /// Get the value returned from the process when it exited/returned.
+ int32_t getReturnValue() const { return m_returnValue; }
- /// True if the process has terminated
+ /// True if the process has terminated
virtual bool isTerminated() = 0;
- /// Blocks until the process has terminated or the timeout completes
- /// Can optionally supply a timeout time. -1 means 'infinite' and is the default.
- /// Note that the timeOut is only used approximately.
- /// Returns true if has terminated.
+ /// Blocks until the process has terminated or the timeout completes
+ /// Can optionally supply a timeout time. -1 means 'infinite' and is the default.
+ /// Note that the timeOut is only used approximately.
+ /// Returns true if has terminated.
virtual bool waitForTermination(Int timeOutInMs = -1) = 0;
- /// Terminate the process gracefully.
- /// After calling it may take time before the process actually terminates
- /// Ie calling isTerminated directly after `terminate` may return false.
- /// The return code depending on implementation/termination style, may not be set.
+ /// Terminate the process gracefully.
+ /// After calling it may take time before the process actually terminates
+ /// Ie calling isTerminated directly after `terminate` may return false.
+ /// The return code depending on implementation/termination style, may not be set.
virtual void terminate(int32_t returnCode) = 0;
- /// Kill the process - attempt to terminate immediately.
+ /// Kill the process - attempt to terminate immediately.
virtual void kill(int32_t returnCode) = 0;
- /// The quoting style used for the command line on this target. Currently just uses Space,
- /// but in future may take into account platform sec
+ /// The quoting style used for the command line on this target. Currently just uses Space,
+ /// but in future may take into account platform sec
static StringEscapeHandler* getEscapeHandler();
- /// Get the suffix used on this platform
+ /// Get the suffix used on this platform
static UnownedStringSlice getExecutableSuffix();
- /// Create a process using the executable/args defined from the commandLine
- static SlangResult create(const CommandLine& commandLine, Process::Flags flags, RefPtr<Process>& outProcess);
+ /// Create a process using the executable/args defined from the commandLine
+ static SlangResult create(
+ const CommandLine& commandLine,
+ Process::Flags flags,
+ RefPtr<Process>& outProcess);
- /// Sleep the current thread for time specified in milliseconds. 0 indicates to OS ok to yield this thread.
+ /// Sleep the current thread for time specified in milliseconds. 0 indicates to OS ok to yield
+ /// this thread.
static void sleepCurrentThread(Int timeInMs);
- /// Get a standard stream
+ /// Get a standard stream
static SlangResult getStdStream(StdStreamType type, RefPtr<Stream>& out);
- /// Get the clock frequency
+ /// Get the clock frequency
static uint64_t getClockFrequency();
- /// Get the clock tick.
+ /// Get the clock tick.
static uint64_t getClockTick();
static uint32_t getId();
protected:
- int32_t m_returnValue = 0; ///< Value returned if process terminated
- RefPtr<Stream> m_streams[Index(StdStreamType::CountOf)]; ///< Streams to communicate with the process
+ int32_t m_returnValue = 0; ///< Value returned if process terminated
+ RefPtr<Stream>
+ m_streams[Index(StdStreamType::CountOf)]; ///< Streams to communicate with the process
};
-}
+} // namespace Slang
#endif // SLANG_PROCESS_H
diff --git a/source/core/slang-random-generator.cpp b/source/core/slang-random-generator.cpp
index 315678f0a..26781b582 100644
--- a/source/core/slang-random-generator.cpp
+++ b/source/core/slang-random-generator.cpp
@@ -1,7 +1,8 @@
#include "slang-random-generator.h"
-namespace Slang {
+namespace Slang
+{
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!! RandomGenerator !!!!!!!!!!!!!!!!!!!!!!!! */
@@ -20,8 +21,8 @@ bool RandomGenerator::nextBool()
bits = ((bits & 0x44444444) >> 2) ^ (bits & 0x11111111);
bits = ((bits & 0x10101010) >> 4) ^ (bits & 0x01010101);
- // In effect is the xor of all the bits of the original last byte
- return ( bits & 1) != 0;
+ // In effect is the xor of all the bits of the original last byte
+ return (bits & 1) != 0;
}
int64_t RandomGenerator::nextInt64()
@@ -34,7 +35,7 @@ int64_t RandomGenerator::nextInt64()
uint32_t RandomGenerator::nextUInt32InRange(uint32_t min, uint32_t max)
{
- // Make sure max is at least in
+ // Make sure max is at least in
max = (max >= min) ? max : min;
// Make 64 bit so can be lazier than having to take care of 32 bit overflow/underflow issues
@@ -49,7 +50,7 @@ uint32_t RandomGenerator::nextUInt32InRange(uint32_t min, uint32_t max)
int32_t RandomGenerator::nextInt32InRange(int32_t min, int32_t max)
{
- // Make sure max is at least in
+ // Make sure max is at least in
max = (max >= min) ? max : min;
// Make 64 bit so can be lazier than having to take care of 32 bit overflow/underflow issues
@@ -90,7 +91,7 @@ static uint8_t* _nextData(RandomGenerator* rand, uint8_t* out, size_t size)
void RandomGenerator::nextData(void* out, size_t size)
{
uint8_t* dst = (uint8_t*)out;
- uint8_t*const end = dst + size;
+ uint8_t* const end = dst + size;
// For short runs just output
if (size <= 4)
@@ -98,7 +99,7 @@ void RandomGenerator::nextData(void* out, size_t size)
_nextData(this, dst, size);
return;
}
-
+
{
const size_t preAlign = size_t(((size_t(dst) + 3) & ~size_t(3)) - size_t(dst));
dst = _nextData(this, dst, preAlign);
@@ -122,7 +123,7 @@ void RandomGenerator::nextData(void* out, size_t size)
_nextData(this, dst, size_t(end - dst));
}
-/* static */RandomGenerator* RandomGenerator::create(int32_t seed)
+/* static */ RandomGenerator* RandomGenerator::create(int32_t seed)
{
return new DefaultRandomGenerator(seed);
}
@@ -149,7 +150,7 @@ void Mt19937RandomGenerator::_generate()
const uint32_t xorValue = 2567483615u;
for (int i = 0; i < kNumEntries - 1; ++i)
{
- const uint32_t y = (m_mt[i] & 0x80000000) + (m_mt[i + 1] & 0x7fffffff);
+ const uint32_t y = (m_mt[i] & 0x80000000) + (m_mt[i + 1] & 0x7fffffff);
// o = (i + 397) % kNumEntries
int32_t o = i + 397;
@@ -200,7 +201,7 @@ int32_t Mt19937RandomGenerator::nextInt32()
uint32_t y = m_mt[m_index++];
y = y ^ (y >> 11);
y = y ^ ((y << 7) & uint32_t(0x9d2c5680u));
- y = y ^ ((y << 15) & uint32_t(0xefc6000u));
+ y = y ^ ((y << 15) & uint32_t(0xefc6000u));
y = y ^ (y >> 18);
return int32_t(y);
diff --git a/source/core/slang-random-generator.h b/source/core/slang-random-generator.h
index fa83fec3b..02bf18af2 100644
--- a/source/core/slang-random-generator.h
+++ b/source/core/slang-random-generator.h
@@ -1,78 +1,86 @@
#ifndef SLANG_CORE_RANDOM_GENERATOR_H
#define SLANG_CORE_RANDOM_GENERATOR_H
+#include "slang-smart-pointer.h"
#include "slang.h"
#include <stdlib.h>
#include <string.h>
-#include "slang-smart-pointer.h"
-
-namespace Slang {
-
-class RandomGenerator: public RefObject
+namespace Slang
{
- public:
- /// Make a copy of the generator in the same state
+class RandomGenerator : public RefObject
+{
+public:
+ /// Make a copy of the generator in the same state
virtual RandomGenerator* clone() = 0;
- /// Reset with a seed
+ /// Reset with a seed
virtual void reset(int32_t seed) = 0;
- /// Next int32_t random number
+ /// Next int32_t random number
virtual int32_t nextInt32() = 0;
- /// Next int64_t random number
+ /// Next int64_t random number
virtual int64_t nextInt64();
- /// Get a 0-1 range floating point
+ /// Get a 0-1 range floating point
virtual float nextUnitFloat32();
-
- /// Get the next bool
+
+ /// Get the next bool
virtual bool nextBool();
- /// Get multiple int32s
+ /// Get multiple int32s
virtual void nextInt32s(int32_t* dst, size_t count) = 0;
- /// Next uint32_t
+ /// Next uint32_t
uint32_t nextUInt32() { return uint32_t(nextInt32()); }
- /// Next Int32 which can only be positive
+ /// Next Int32 which can only be positive
int32_t nextPositiveInt32() { return nextInt32() & 0x7fffffff; }
- /// Next Int64 which can only be positive
+ /// Next Int64 which can only be positive
int64_t nextPositiveInt64() { return nextInt64() & SLANG_INT64(0x7fffffffffffffff); }
- /// Returns value up to BUT NOT INCLUDING maxValue.
- int32_t nextInt32UpTo(int32_t maxValue) { assert(maxValue > 0); return (maxValue <= 1) ? 0 : (nextPositiveInt32() % maxValue); }
+ /// Returns value up to BUT NOT INCLUDING maxValue.
+ int32_t nextInt32UpTo(int32_t maxValue)
+ {
+ assert(maxValue > 0);
+ return (maxValue <= 1) ? 0 : (nextPositiveInt32() % maxValue);
+ }
- /// Returns value from min up to BUT NOT INCLUDING max.
+ /// Returns value from min up to BUT NOT INCLUDING max.
int32_t nextInt32InRange(int32_t min, int32_t max);
/// Returns value from min up to BUT NOT INCLUDING max
uint32_t nextUInt32InRange(uint32_t min, uint32_t max);
- /// Returns value up to BUT NOT INCLUDING maxValue
- int64_t nextInt64UpTo(int64_t maxValue) { assert(maxValue > 0); return (maxValue <= 1) ? 0 : (nextPositiveInt64() % maxValue); }
+ /// Returns value up to BUT NOT INCLUDING maxValue
+ int64_t nextInt64UpTo(int64_t maxValue)
+ {
+ assert(maxValue > 0);
+ return (maxValue <= 1) ? 0 : (nextPositiveInt64() % maxValue);
+ }
- /// Returns value from min up to BUT NOT INCLUDING max
+ /// Returns value from min up to BUT NOT INCLUDING max
int64_t nextInt64InRange(int64_t min, int64_t max);
- /// Fill with random data.
- /// NOTE! Output is only identical bytes if generator in same state *and* size_t(dst) & 3 is the same on calls.
+ /// Fill with random data.
+ /// NOTE! Output is only identical bytes if generator in same state *and* size_t(dst) & 3 is the
+ /// same on calls.
void nextData(void* dst, size_t size);
- /// Create a RandomGenerator with specified seed using default generator type
+ /// Create a RandomGenerator with specified seed using default generator type
static RandomGenerator* create(int32_t seed);
};
-/* Mersenne Twister random number generator
+/* Mersenne Twister random number generator
https://en.wikipedia.org/wiki/Mersenne_Twister
*/
-class Mt19937RandomGenerator: public RandomGenerator
+class Mt19937RandomGenerator : public RandomGenerator
{
- public:
+public:
typedef Mt19937RandomGenerator ThisType;
- enum
+ enum
{
kNumEntries = 624
};
@@ -82,24 +90,23 @@ class Mt19937RandomGenerator: public RandomGenerator
int32_t nextInt32() SLANG_OVERRIDE;
void nextInt32s(int32_t* dst, size_t count) SLANG_OVERRIDE;
- /// Ctor
+ /// Ctor
Mt19937RandomGenerator();
Mt19937RandomGenerator(const ThisType& rhs);
explicit Mt19937RandomGenerator(int32_t seed);
- /// Assignment
+ /// Assignment
void operator=(const ThisType& rhs)
{
m_index = rhs.m_index;
::memcpy(m_mt, rhs.m_mt, sizeof(m_mt));
}
-
- protected:
- void _generate();
- uint32_t m_mt[kNumEntries]; ///< The random state vector
- int m_index; ///< If set to >= kMaxEntries it means reset
+protected:
+ void _generate();
+ uint32_t m_mt[kNumEntries]; ///< The random state vector
+ int m_index; ///< If set to >= kMaxEntries it means reset
};
typedef Mt19937RandomGenerator DefaultRandomGenerator;
diff --git a/source/core/slang-range.h b/source/core/slang-range.h
index 6e4419ce0..e85ce6a9d 100644
--- a/source/core/slang-range.h
+++ b/source/core/slang-range.h
@@ -3,27 +3,24 @@
namespace Slang
{
- template<typename T>
- struct Range
- {
- T begin = 0;
- T end = 0;
-
- bool inRange(T val) const
- {
- return val >= begin && val < end;
- }
- };
+template<typename T>
+struct Range
+{
+ T begin = 0;
+ T end = 0;
- template <typename T>
- Range<T> makeRange(T begin, T end)
- {
- Range<T> result;
- result.begin = begin;
- result.end = end;
- return result;
- }
+ bool inRange(T val) const { return val >= begin && val < end; }
+};
+template<typename T>
+Range<T> makeRange(T begin, T end)
+{
+ Range<T> result;
+ result.begin = begin;
+ result.end = end;
+ return result;
}
-#endif //SLANG_CORE_RANGE_H
+} // namespace Slang
+
+#endif // SLANG_CORE_RANGE_H
diff --git a/source/core/slang-render-api-util.cpp b/source/core/slang-render-api-util.cpp
index 797d82cd7..476188abd 100644
--- a/source/core/slang-render-api-util.cpp
+++ b/source/core/slang-render-api-util.cpp
@@ -1,25 +1,23 @@
#include "slang-render-api-util.h"
-#include "slang.h"
-
#include "slang-list.h"
-#include "slang-string-util.h"
-
#include "slang-platform.h"
+#include "slang-string-util.h"
+#include "slang.h"
-namespace Slang {
+namespace Slang
+{
// NOTE! Must keep in same order as RenderApiType and have same amount of entries
-/* static */const RenderApiUtil::Info RenderApiUtil::s_infos[] =
-{
- { RenderApiType::Vulkan, "vk,vulkan", ""},
- { RenderApiType::D3D12, "dx12,d3d12", ""},
- { RenderApiType::D3D11, "dx11,d3d11", "hlsl,hlsl-rewrite,slang"},
- { RenderApiType::Metal, "mtl,metal", ""},
- { RenderApiType::CPU, "cpu", ""},
- { RenderApiType::CUDA, "cuda", "cuda,ptx"},
- { RenderApiType::WebGPU, "wgpu,webgpu", "wgsl"},
+/* static */ const RenderApiUtil::Info RenderApiUtil::s_infos[] = {
+ {RenderApiType::Vulkan, "vk,vulkan", ""},
+ {RenderApiType::D3D12, "dx12,d3d12", ""},
+ {RenderApiType::D3D11, "dx11,d3d11", "hlsl,hlsl-rewrite,slang"},
+ {RenderApiType::Metal, "mtl,metal", ""},
+ {RenderApiType::CPU, "cpu", ""},
+ {RenderApiType::CUDA, "cuda", "cuda,ptx"},
+ {RenderApiType::WebGPU, "wgpu,webgpu", "wgsl"},
};
static int _calcAvailableApis()
@@ -36,7 +34,7 @@ static int _calcAvailableApis()
return flags;
}
-/* static */int RenderApiUtil::getAvailableApis()
+/* static */ int RenderApiUtil::getAvailableApis()
{
static int s_availableApis = _calcAvailableApis();
return s_availableApis;
@@ -53,7 +51,7 @@ UnownedStringSlice RenderApiUtil::getApiName(RenderApiType type)
return StringUtil::getAtInSplit(UnownedStringSlice(s_infos[index].names), ',', 0);
}
-/* static */RenderApiType RenderApiUtil::findApiTypeByName(const Slang::UnownedStringSlice& name)
+/* static */ RenderApiType RenderApiUtil::findApiTypeByName(const Slang::UnownedStringSlice& name)
{
using namespace Slang;
List<UnownedStringSlice> namesList;
@@ -78,7 +76,9 @@ UnownedStringSlice RenderApiUtil::getApiName(RenderApiType type)
return RenderApiType::Unknown;
}
-/* static */ Slang::Result RenderApiUtil::findApiFlagsByName(const Slang::UnownedStringSlice& name, RenderApiFlags* flagsOut)
+/* static */ Slang::Result RenderApiUtil::findApiFlagsByName(
+ const Slang::UnownedStringSlice& name,
+ RenderApiFlags* flagsOut)
{
// Special case 'all'
if (name == "all")
@@ -102,7 +102,7 @@ UnownedStringSlice RenderApiUtil::getApiName(RenderApiType type)
static bool isNameStartChar(char c)
{
- return (c >= 'a' && c <='z') || (c >= 'A' && c <= 'Z') || (c == '_');
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_');
}
static bool isNameNextChar(char c)
@@ -110,15 +110,16 @@ static bool isNameNextChar(char c)
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9');
}
-namespace { // anonymous
-enum class Token
+namespace
+{ // anonymous
+enum class Token
{
eError,
eOp,
eId,
eEnd,
};
-}
+} // namespace
static Token nextToken(Slang::UnownedStringSlice& textInOut, Slang::UnownedStringSlice& lexemeOut)
{
@@ -154,18 +155,21 @@ static Token nextToken(Slang::UnownedStringSlice& textInOut, Slang::UnownedStrin
return Token::eId;
}
-/* static */Slang::Result RenderApiUtil::parseApiFlags(const Slang::UnownedStringSlice& textIn, RenderApiFlags initialFlags, RenderApiFlags* apiFlagsOut)
+/* static */ Slang::Result RenderApiUtil::parseApiFlags(
+ const Slang::UnownedStringSlice& textIn,
+ RenderApiFlags initialFlags,
+ RenderApiFlags* apiFlagsOut)
{
using namespace Slang;
UnownedStringSlice text(textIn);
UnownedStringSlice lexeme;
- RenderApiFlags apiFlags = 0;
-
+ RenderApiFlags apiFlags = 0;
+
switch (nextToken(text, lexeme))
{
- case Token::eOp:
+ case Token::eOp:
{
// If we start with an op - we use the passed in values as the default
// Rewind back to the start
@@ -173,27 +177,27 @@ static Token nextToken(Slang::UnownedStringSlice& textInOut, Slang::UnownedStrin
apiFlags = initialFlags;
break;
}
- case Token::eId:
+ case Token::eId:
{
// If we start with an Id - we use that as the starting state
SLANG_RETURN_ON_FAIL(findApiFlagsByName(lexeme, &apiFlags));
break;
}
- default: return SLANG_FAIL;
+ default: return SLANG_FAIL;
}
-
+
while (true)
{
// Must have an op followed by an id unless we are at the end
switch (nextToken(text, lexeme))
{
- case Token::eEnd:
+ case Token::eEnd:
{
*apiFlagsOut = apiFlags;
return SLANG_OK;
}
- case Token::eOp: break;
- default: return SLANG_FAIL;
+ case Token::eOp: break;
+ default: return SLANG_FAIL;
}
const char op = lexeme[0];
@@ -216,7 +220,7 @@ static Token nextToken(Slang::UnownedStringSlice& textInOut, Slang::UnownedStrin
}
}
-/* static */RenderApiType RenderApiUtil::findRenderApiType(const Slang::UnownedStringSlice& text)
+/* static */ RenderApiType RenderApiUtil::findRenderApiType(const Slang::UnownedStringSlice& text)
{
using namespace Slang;
for (Index j = 0; j < SLANG_COUNT_OF(RenderApiUtil::s_infos); j++)
@@ -231,7 +235,8 @@ static Token nextToken(Slang::UnownedStringSlice& textInOut, Slang::UnownedStrin
return RenderApiType::Unknown;
}
-/* static */RenderApiType RenderApiUtil::findImplicitLanguageRenderApiType(const Slang::UnownedStringSlice& text)
+/* static */ RenderApiType RenderApiUtil::findImplicitLanguageRenderApiType(
+ const Slang::UnownedStringSlice& text)
{
using namespace Slang;
for (Index j = 0; j < SLANG_COUNT_OF(RenderApiUtil::s_infos); j++)
@@ -260,32 +265,34 @@ static bool _canLoadSharedLibrary(const char* libName)
}
#endif
-/* static */bool RenderApiUtil::calcHasApi(RenderApiType type)
+/* static */ bool RenderApiUtil::calcHasApi(RenderApiType type)
{
switch (type)
{
#if SLANG_WINDOWS_FAMILY
- case RenderApiType::Vulkan: return _canLoadSharedLibrary("vulkan-1") || _canLoadSharedLibrary("vk_swiftshader");
- case RenderApiType::WebGPU:
- return _canLoadSharedLibrary("webgpu_dawn") &&
- _canLoadSharedLibrary("dxcompiler") &&
- _canLoadSharedLibrary("dxil");
+ case RenderApiType::Vulkan:
+ return _canLoadSharedLibrary("vulkan-1") || _canLoadSharedLibrary("vk_swiftshader");
+ case RenderApiType::WebGPU:
+ return _canLoadSharedLibrary("webgpu_dawn") && _canLoadSharedLibrary("dxcompiler") &&
+ _canLoadSharedLibrary("dxil");
#elif SLANG_APPLE_FAMILY
- case RenderApiType::Vulkan: return true;
- case RenderApiType::Metal: return true;
+ case RenderApiType::Vulkan: return true;
+ case RenderApiType::Metal: return true;
#elif SLANG_UNIX_FAMILY
- case RenderApiType::Vulkan: return true;
+ case RenderApiType::Vulkan: return true;
#endif
#if SLANG_ENABLE_DIRECTX
- case RenderApiType::D3D11: return _canLoadSharedLibrary(SLANG_ENABLE_DXVK ? "dxvk_d3d11" : "d3d11");
- case RenderApiType::D3D12: return _canLoadSharedLibrary(SLANG_ENABLE_VKD3D ? "vkd3d-proton-d3d12" : "d3d12");
+ case RenderApiType::D3D11:
+ return _canLoadSharedLibrary(SLANG_ENABLE_DXVK ? "dxvk_d3d11" : "d3d11");
+ case RenderApiType::D3D12:
+ return _canLoadSharedLibrary(SLANG_ENABLE_VKD3D ? "vkd3d-proton-d3d12" : "d3d12");
#endif
- case RenderApiType::CPU: return true;
- // We'll assume CUDA is available, and if not, trying to create it will detect it
- case RenderApiType::CUDA: return true;
- default: break;
+ case RenderApiType::CPU: return true;
+ // We'll assume CUDA is available, and if not, trying to create it will detect it
+ case RenderApiType::CUDA: return true;
+ default: break;
}
return false;
}
diff --git a/source/core/slang-render-api-util.h b/source/core/slang-render-api-util.h
index f1be930cc..b1fae8c37 100644
--- a/source/core/slang-render-api-util.h
+++ b/source/core/slang-render-api-util.h
@@ -2,7 +2,6 @@
#define SLANG_CORE_RENDER_API_UTIL_H
#include "../../source/core/slang-string.h"
-
#include "slang-com-helper.h"
namespace Slang
@@ -21,7 +20,8 @@ enum class RenderApiType
CountOf,
};
-// Use a struct wrapped Enum instead of enum class, cos we want to be able to manipulate as integrals
+// Use a struct wrapped Enum instead of enum class, cos we want to be able to manipulate as
+// integrals
struct RenderApiFlag
{
enum Enum
@@ -30,10 +30,10 @@ struct RenderApiFlag
D3D12 = 1 << int(RenderApiType::D3D12),
D3D11 = 1 << int(RenderApiType::D3D11),
Metal = 1 << int(RenderApiType::Metal),
- CPU = 1 << int(RenderApiType::CPU),
- CUDA = 1 << int(RenderApiType::CUDA),
+ CPU = 1 << int(RenderApiType::CPU),
+ CUDA = 1 << int(RenderApiType::CUDA),
WebGPU = 1 << int(RenderApiType::WebGPU),
- AllOf = (1 << int(RenderApiType::CountOf)) - 1 ///< All bits set
+ AllOf = (1 << int(RenderApiType::CountOf)) - 1 ///< All bits set
};
};
typedef uint32_t RenderApiFlags;
@@ -42,40 +42,47 @@ struct RenderApiUtil
{
struct Info
{
- RenderApiType type; ///< The type
- const char* names; ///< Comma separated list of names associated with the type
- const char* languageNames; ///< Comma separated list of target language names associated with the type
+ RenderApiType type; ///< The type
+ const char* names; ///< Comma separated list of names associated with the type
+ const char* languageNames; ///< Comma separated list of target language names associated
+ ///< with the type
};
- /// Returns true if the API is available.
+ /// Returns true if the API is available.
static bool calcHasApi(RenderApiType type);
- /// Returns a combination of RenderApiFlag bits which if set indicates that the API is available.
+ /// Returns a combination of RenderApiFlag bits which if set indicates that the API is
+ /// available.
static int getAvailableApis();
- /// Get the name
+ /// Get the name
static UnownedStringSlice getApiName(RenderApiType type);
- /// Returns RenderApiType::Unknown if not found
+ /// Returns RenderApiType::Unknown if not found
static RenderApiType findApiTypeByName(const Slang::UnownedStringSlice& name);
- /// FlagsOut will have flag/flags specified by a name if returns with successful result code.
- static Slang::Result findApiFlagsByName(const Slang::UnownedStringSlice& name, RenderApiFlags* flagsOut);
-
- /// Parse api flags string, returning SLANG_OK on success.
- /// If first character is + or - the flags will be applied to initialFlags, else initialFlags is ignored.
- /// For example "all-dx12" would be all apis, except dx12
- /// -vk would be whatever is in initial flags, but not vulkan.
- static Slang::Result parseApiFlags(const Slang::UnownedStringSlice& text, RenderApiFlags initialFlags, RenderApiFlags* apiBitsOut);
-
- /// Gets the API type from a string, or returns RenderApiType::Unknown if not found
+ /// FlagsOut will have flag/flags specified by a name if returns with successful result code.
+ static Slang::Result findApiFlagsByName(
+ const Slang::UnownedStringSlice& name,
+ RenderApiFlags* flagsOut);
+
+ /// Parse api flags string, returning SLANG_OK on success.
+ /// If first character is + or - the flags will be applied to initialFlags, else initialFlags is
+ /// ignored. For example "all-dx12" would be all apis, except dx12 -vk would be whatever is in
+ /// initial flags, but not vulkan.
+ static Slang::Result parseApiFlags(
+ const Slang::UnownedStringSlice& text,
+ RenderApiFlags initialFlags,
+ RenderApiFlags* apiBitsOut);
+
+ /// Gets the API type from a string, or returns RenderApiType::Unknown if not found
static RenderApiType findRenderApiType(const Slang::UnownedStringSlice& text);
static RenderApiType findImplicitLanguageRenderApiType(const Slang::UnownedStringSlice& text);
- /// Get information about a render API
+ /// Get information about a render API
static const Info& getInfo(RenderApiType type) { return s_infos[int(type)]; }
- /// Static information about each render api
+ /// Static information about each render api
static const Info s_infos[int(RenderApiType::CountOf)];
};
diff --git a/source/core/slang-riff-file-system.cpp b/source/core/slang-riff-file-system.cpp
index 1072db186..b290ee5e5 100644
--- a/source/core/slang-riff-file-system.cpp
+++ b/source/core/slang-riff-file-system.cpp
@@ -1,10 +1,9 @@
#include "slang-riff-file-system.h"
+#include "slang-blob.h"
#include "slang-com-helper.h"
#include "slang-com-ptr.h"
-#include "slang-blob.h"
-
// Compression systems
#include "slang-deflate-compression-system.h"
#include "slang-lz4-compression-system.h"
@@ -12,8 +11,8 @@
namespace Slang
{
-RiffFileSystem::RiffFileSystem(ICompressionSystem* compressionSystem):
- m_compressionSystem(compressionSystem)
+RiffFileSystem::RiffFileSystem(ICompressionSystem* compressionSystem)
+ : m_compressionSystem(compressionSystem)
{
}
@@ -57,7 +56,11 @@ SlangResult RiffFileSystem::loadFile(char const* path, ISlangBlob** outBlob)
// Okay lets decompress into a blob
ScopedAllocation alloc;
void* dst = alloc.allocateTerminated(entry->m_uncompressedSizeInBytes);
- SLANG_RETURN_ON_FAIL(m_compressionSystem->decompress(contents->getBufferPointer(), contents->getBufferSize(), entry->m_uncompressedSizeInBytes, dst));
+ SLANG_RETURN_ON_FAIL(m_compressionSystem->decompress(
+ contents->getBufferPointer(),
+ contents->getBufferSize(),
+ entry->m_uncompressedSizeInBytes,
+ dst));
auto blob = RawBlob::moveCreate(alloc);
@@ -74,7 +77,7 @@ SlangResult RiffFileSystem::loadFile(char const* path, ISlangBlob** outBlob)
}
SlangResult RiffFileSystem::saveFile(const char* path, const void* data, size_t size)
-{
+{
Entry* entry;
SLANG_RETURN_ON_FAIL(_requireFile(path, &entry));
@@ -82,7 +85,8 @@ SlangResult RiffFileSystem::saveFile(const char* path, const void* data, size_t
if (m_compressionSystem)
{
// Lets try compressing the input
- SLANG_RETURN_ON_FAIL(m_compressionSystem->compress(&m_compressionStyle, data, size, contents.writeRef()));
+ SLANG_RETURN_ON_FAIL(
+ m_compressionSystem->compress(&m_compressionStyle, data, size, contents.writeRef()));
}
else
{
@@ -129,28 +133,29 @@ SlangResult RiffFileSystem::loadArchive(const void* archive, size_t archiveSizeI
_clear();
// Find the header
- const auto header = rootList->findContainedData<RiffFileSystemBinary::Header>(RiffFileSystemBinary::kHeaderFourCC);
+ const auto header = rootList->findContainedData<RiffFileSystemBinary::Header>(
+ RiffFileSystemBinary::kHeaderFourCC);
CompressionSystemType compressionType = CompressionSystemType(header->compressionSystemType);
switch (compressionType)
{
- case CompressionSystemType::None:
+ case CompressionSystemType::None:
{
// Null m_compressionSystem means no compression
m_compressionSystem.setNull();
break;
}
- case CompressionSystemType::Deflate:
+ case CompressionSystemType::Deflate:
{
m_compressionSystem = DeflateCompressionSystem::getSingleton();
break;
}
- case CompressionSystemType::LZ4:
+ case CompressionSystemType::LZ4:
{
m_compressionSystem = LZ4CompressionSystem::getSingleton();
break;
}
- default: return SLANG_FAIL;
+ default: return SLANG_FAIL;
}
// Read all of the contained data
@@ -175,7 +180,9 @@ SlangResult RiffFileSystem::loadArchive(const void* archive, size_t archiveSizeI
srcData += sizeof(*srcEntry);
// Check if seems plausible
- if (sizeof(RiffFileSystemBinary::Entry) + srcEntry->compressedSize + srcEntry->pathSize != dataSize)
+ if (sizeof(RiffFileSystemBinary::Entry) + srcEntry->compressedSize +
+ srcEntry->pathSize !=
+ dataSize)
{
return SLANG_FAIL;
}
@@ -188,10 +195,10 @@ SlangResult RiffFileSystem::loadArchive(const void* archive, size_t archiveSizeI
dstEntry.m_canonicalPath = UnownedStringSlice(path, srcEntry->pathSize - 1);
dstEntry.m_type = (SlangPathType)srcEntry->pathType;
dstEntry.m_uncompressedSizeInBytes = srcEntry->uncompressedSize;
-
+
switch (dstEntry.m_type)
{
- case SLANG_PATH_TYPE_FILE:
+ case SLANG_PATH_TYPE_FILE:
{
if (srcData + srcEntry->compressedSize != data->getPayloadEnd())
{
@@ -202,8 +209,8 @@ SlangResult RiffFileSystem::loadArchive(const void* archive, size_t archiveSizeI
dstEntry.m_contents = RawBlob::create(srcData, srcEntry->compressedSize);
break;
}
- case SLANG_PATH_TYPE_DIRECTORY: break;
- default: return SLANG_FAIL;
+ case SLANG_PATH_TYPE_DIRECTORY: break;
+ default: return SLANG_FAIL;
}
// If it's the root entry we can ignore (as already added)
@@ -226,11 +233,16 @@ SlangResult RiffFileSystem::storeArchive(bool blobOwnsContent, ISlangBlob** outB
SLANG_UNUSED(blobOwnsContent)
RiffContainer container;
- RiffContainer::ScopeChunk scopeContainer(&container, RiffContainer::Chunk::Kind::List, RiffFileSystemBinary::kContainerFourCC);
+ RiffContainer::ScopeChunk scopeContainer(
+ &container,
+ RiffContainer::Chunk::Kind::List,
+ RiffFileSystemBinary::kContainerFourCC);
{
RiffFileSystemBinary::Header header;
- CompressionSystemType compressionSystemType = m_compressionSystem ? m_compressionSystem->getSystemType() : CompressionSystemType::None;
+ CompressionSystemType compressionSystemType = m_compressionSystem
+ ? m_compressionSystem->getSystemType()
+ : CompressionSystemType::None;
header.compressionSystemType = uint32_t(compressionSystemType);
container.addDataChunk(RiffFileSystemBinary::kHeaderFourCC, &header, sizeof(header));
}
@@ -243,7 +255,10 @@ SlangResult RiffFileSystem::storeArchive(bool blobOwnsContent, ISlangBlob** outB
continue;
}
- RiffContainer::ScopeChunk scopeData(&container, RiffContainer::Chunk::Kind::Data, RiffFileSystemBinary::kEntryFourCC);
+ RiffContainer::ScopeChunk scopeData(
+ &container,
+ RiffContainer::Chunk::Kind::Data,
+ RiffFileSystemBinary::kEntryFourCC);
RiffFileSystemBinary::Entry dstEntry;
dstEntry.uncompressedSize = 0;
@@ -263,13 +278,18 @@ SlangResult RiffFileSystem::storeArchive(bool blobOwnsContent, ISlangBlob** outB
container.write(&dstEntry, sizeof(dstEntry));
// Path
- container.write(srcEntry.m_canonicalPath.getBuffer(), srcEntry.m_canonicalPath.getLength() + 1);
+ container.write(
+ srcEntry.m_canonicalPath.getBuffer(),
+ srcEntry.m_canonicalPath.getLength() + 1);
// Add the contained data without copying
if (blob)
{
RiffContainer::Data* data = container.addData();
- container.setUnowned(data, const_cast<void*>(blob->getBufferPointer()), blob->getBufferSize());
+ container.setUnowned(
+ data,
+ const_cast<void*>(blob->getBufferPointer()),
+ blob->getBufferSize());
}
}
@@ -284,11 +304,12 @@ SlangResult RiffFileSystem::storeArchive(bool blobOwnsContent, ISlangBlob** outB
return SLANG_OK;
}
-/* static */bool RiffFileSystem::isArchive(const void* data, size_t sizeInBytes)
+/* static */ bool RiffFileSystem::isArchive(const void* data, size_t sizeInBytes)
{
MemoryStreamBase stream(FileAccess::Read, data, sizeInBytes);
RiffListHeader header;
- return SLANG_SUCCEEDED(RiffUtil::readHeader(&stream, header)) && header.subType == RiffFileSystemBinary::kContainerFourCC;
+ return SLANG_SUCCEEDED(RiffUtil::readHeader(&stream, header)) &&
+ header.subType == RiffFileSystemBinary::kContainerFourCC;
}
} // namespace Slang
diff --git a/source/core/slang-riff-file-system.h b/source/core/slang-riff-file-system.h
index 60e5a7ae2..6eda1a371 100644
--- a/source/core/slang-riff-file-system.h
+++ b/source/core/slang-riff-file-system.h
@@ -3,7 +3,6 @@
#include "slang-archive-file-system.h"
#include "slang-memory-file-system.h"
-
#include "slang-riff.h"
namespace Slang
@@ -18,33 +17,37 @@ struct RiffFileSystemBinary
struct Header
{
- uint32_t compressionSystemType; /// One of CompressionSystemType
+ uint32_t compressionSystemType; /// One of CompressionSystemType
};
struct Entry
{
uint32_t compressedSize;
uint32_t uncompressedSize;
- uint32_t pathSize; ///< The size of the path in bytes, including terminating 0
- uint32_t pathType; ///< One of SlangPathType
+ uint32_t pathSize; ///< The size of the path in bytes, including terminating 0
+ uint32_t pathType; ///< One of SlangPathType
// Followed by the path (including terminating 0)
// Followed by the compressed data
};
};
-/* RiffFileSystem implements ISlangMutableFileSystem and can be used to save and load the whole of it's contents as an 'archive' blob.
+/* RiffFileSystem implements ISlangMutableFileSystem and can be used to save and load the whole of
+it's contents as an 'archive' blob.
-The 'RIFF' part provides the structure to store out the contents. The data is only accessed in the RIFF format when being
-read/written to an archive. Normal operations on the file system act in memory.
+The 'RIFF' part provides the structure to store out the contents. The data is only accessed in the
+RIFF format when being read/written to an archive. Normal operations on the file system act in
+memory.
-A RiffFileSystem allows for compression to be used on files. To use compression pass in a suitable ICompressionSystem
-implementation on construction. If constructed without an ICompressionSystem, data is stored uncompressed. When compression is
-used, files 'contents' blob is actually the *compressed* version of the contents. Calling loadFile/saveFile will
-uncompress/compress as need. If there is no compression contents is identical to the file contents.
+A RiffFileSystem allows for compression to be used on files. To use compression pass in a suitable
+ICompressionSystem implementation on construction. If constructed without an ICompressionSystem,
+data is stored uncompressed. When compression is used, files 'contents' blob is actually the
+*compressed* version of the contents. Calling loadFile/saveFile will uncompress/compress as need. If
+there is no compression contents is identical to the file contents.
NOTE:
-* The RIFF chunk IDs are *slang specific*. It conforms to RIFF but is unlikely to be usable with other tooling.
+* The RIFF chunk IDs are *slang specific*. It conforms to RIFF but is unlikely to be usable with
+other tooling.
* The RIFF chunk IDs are in RiffFileSystemBinary struct
*/
class RiffFileSystem : public MemoryFileSystem, public IArchiveFileSystem
@@ -52,28 +55,37 @@ class RiffFileSystem : public MemoryFileSystem, public IArchiveFileSystem
public:
typedef MemoryFileSystem Super;
- // ISlangUnknown
+ // ISlangUnknown
SLANG_COM_BASE_IUNKNOWN_ALL
// ISlangCastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// ISlangFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob)
+ SLANG_OVERRIDE;
// ISlangModifyableFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
// IArchiveFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadArchive(const void* archive, size_t archiveSizeInBytes) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL storeArchive(bool blobOwnsContent, ISlangBlob** outBlob) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW void SLANG_MCALL setCompressionStyle(const CompressionStyle& style) SLANG_OVERRIDE { m_compressionStyle = style; }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ loadArchive(const void* archive, size_t archiveSizeInBytes) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ storeArchive(bool blobOwnsContent, ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW void SLANG_MCALL setCompressionStyle(const CompressionStyle& style)
+ SLANG_OVERRIDE
+ {
+ m_compressionStyle = style;
+ }
- /// Pass in nullptr, if no compression is wanted.
+ /// Pass in nullptr, if no compression is wanted.
explicit RiffFileSystem(ICompressionSystem* compressionSystem);
- /// True if this appears to be Riff archive
+ /// True if this appears to be Riff archive
static bool isArchive(const void* data, size_t sizeInBytes);
protected:
@@ -85,6 +97,6 @@ protected:
CompressionStyle m_compressionStyle;
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-riff.cpp b/source/core/slang-riff.cpp
index 83693433e..94cd2038e 100644
--- a/source/core/slang-riff.cpp
+++ b/source/core/slang-riff.cpp
@@ -1,19 +1,21 @@
#include "slang-riff.h"
#include "slang-com-helper.h"
-
#include "slang-hex-dump-util.h"
namespace Slang
{
-/* static */int64_t RiffUtil::calcChunkTotalSize(const RiffHeader& chunk)
+/* static */ int64_t RiffUtil::calcChunkTotalSize(const RiffHeader& chunk)
{
size_t size = chunk.size + sizeof(RiffHeader);
return getPadSize(size);
}
-/* static */SlangResult RiffUtil::skip(const RiffHeader& chunk, Stream* stream, int64_t* remainingBytesInOut)
+/* static */ SlangResult RiffUtil::skip(
+ const RiffHeader& chunk,
+ Stream* stream,
+ int64_t* remainingBytesInOut)
{
int64_t chunkSize = calcChunkTotalSize(chunk);
if (remainingBytesInOut)
@@ -26,7 +28,7 @@ namespace Slang
return SLANG_OK;
}
-/* static */SlangResult RiffUtil::readChunk(Stream* stream, RiffHeader& outChunk)
+/* static */ SlangResult RiffUtil::readChunk(Stream* stream, RiffHeader& outChunk)
{
size_t readBytes;
SLANG_RETURN_ON_FAIL(stream->read(&outChunk, sizeof(RiffHeader), readBytes));
@@ -34,7 +36,12 @@ namespace Slang
return (readBytes == sizeof(RiffHeader)) ? SLANG_OK : SLANG_FAIL;
}
-/* static */SlangResult RiffUtil::writeData(const RiffHeader* header, size_t headerSize, const void* payload, size_t payloadSize, Stream* out)
+/* static */ SlangResult RiffUtil::writeData(
+ const RiffHeader* header,
+ size_t headerSize,
+ const void* payload,
+ size_t payloadSize,
+ Stream* out)
{
SLANG_ASSERT(uint64_t(payloadSize) <= uint64_t(0xfffffffff));
SLANG_ASSERT(headerSize >= sizeof(RiffHeader));
@@ -62,14 +69,18 @@ namespace Slang
size_t padSize = getPadSize(payloadSize);
if (padSize - payloadSize)
{
- uint8_t end[kRiffPadSize] = { 0 };
+ uint8_t end[kRiffPadSize] = {0};
SLANG_RETURN_ON_FAIL(out->write(end, padSize - payloadSize));
}
-
+
return SLANG_OK;
}
-/* static */SlangResult RiffUtil::readPayload(Stream* stream, size_t size, void* outData, size_t& outReadSize)
+/* static */ SlangResult RiffUtil::readPayload(
+ Stream* stream,
+ size_t size,
+ void* outData,
+ size_t& outReadSize)
{
outReadSize = 0;
@@ -85,7 +96,11 @@ namespace Slang
return SLANG_OK;
}
-/* static */SlangResult RiffUtil::readData(Stream* stream, RiffHeader* outHeader, size_t headerSize, List<uint8_t>& data)
+/* static */ SlangResult RiffUtil::readData(
+ Stream* stream,
+ RiffHeader* outHeader,
+ size_t headerSize,
+ List<uint8_t>& data)
{
RiffHeader chunk;
SLANG_RETURN_ON_FAIL(readChunk(stream, chunk));
@@ -101,14 +116,14 @@ namespace Slang
{
SLANG_RETURN_ON_FAIL(stream->readExactly(outHeader + 1, headerSize - sizeof(RiffHeader)));
}
-
+
const size_t payloadSize = chunk.size - (headerSize - sizeof(RiffHeader));
size_t readSize;
data.setCount(payloadSize);
return readPayload(stream, payloadSize, data.getBuffer(), readSize);
}
-/* static */SlangResult RiffUtil::readHeader(Stream* stream, RiffListHeader& outHeader)
+/* static */ SlangResult RiffUtil::readHeader(Stream* stream, RiffListHeader& outHeader)
{
// Need to read the chunk header
SLANG_RETURN_ON_FAIL(readChunk(stream, outHeader.chunk));
@@ -117,13 +132,15 @@ namespace Slang
if (isListType(outHeader.chunk.type))
{
// Read the sub type
- SLANG_RETURN_ON_FAIL(stream->readExactly(&outHeader.subType, sizeof(RiffListHeader) - sizeof(RiffHeader)));
+ SLANG_RETURN_ON_FAIL(
+ stream->readExactly(&outHeader.subType, sizeof(RiffListHeader) - sizeof(RiffHeader)));
}
return SLANG_OK;
}
-namespace { // anonymous
+namespace
+{ // anonymous
struct DumpVisitor : public RiffContainer::Visitor
{
@@ -167,10 +184,8 @@ struct DumpVisitor : public RiffContainer::Visitor
return SLANG_OK;
}
- DumpVisitor(WriterHelper writer, Chunk* rootChunk) :
- m_writer(writer),
- m_indent(0),
- m_rootChunk(rootChunk)
+ DumpVisitor(WriterHelper writer, Chunk* rootChunk)
+ : m_writer(writer), m_indent(0), m_rootChunk(rootChunk)
{
}
@@ -199,15 +214,18 @@ struct DumpVisitor : public RiffContainer::Visitor
WriterHelper m_writer;
};
-}
+} // namespace
-/* static */void RiffUtil::dump(RiffContainer::Chunk* chunk, WriterHelper writer)
+/* static */ void RiffUtil::dump(RiffContainer::Chunk* chunk, WriterHelper writer)
{
DumpVisitor visitor(writer, chunk);
chunk->visit(&visitor);
}
-/* static */SlangResult RiffUtil::write(RiffContainer::ListChunk* list, bool isRoot, Stream* stream)
+/* static */ SlangResult RiffUtil::write(
+ RiffContainer::ListChunk* list,
+ bool isRoot,
+ Stream* stream)
{
RiffListHeader listHeader;
@@ -218,20 +236,20 @@ struct DumpVisitor : public RiffContainer::Visitor
// Write the header
SLANG_RETURN_ON_FAIL(stream->write(&listHeader, sizeof(listHeader)));
- // Write the contained chunks
+ // Write the contained chunks
Chunk* chunk = list->m_containedChunks;
while (chunk)
{
switch (chunk->m_kind)
{
- case Chunk::Kind::List:
+ case Chunk::Kind::List:
{
auto listChunk = static_cast<ListChunk*>(chunk);
// It's a container
SLANG_RETURN_ON_FAIL(write(listChunk, false, stream));
break;
}
- case Chunk::Kind::Data:
+ case Chunk::Kind::Data:
{
auto dataChunk = static_cast<DataChunk*>(chunk);
@@ -252,30 +270,31 @@ struct DumpVisitor : public RiffContainer::Visitor
}
// Need to write for alignment
- const size_t remainingSize = getPadSize(dataChunk->m_payloadSize) - dataChunk->m_payloadSize;
+ const size_t remainingSize =
+ getPadSize(dataChunk->m_payloadSize) - dataChunk->m_payloadSize;
if (remainingSize)
{
- static const uint8_t trailing[kRiffPadSize] = { 0 };
+ static const uint8_t trailing[kRiffPadSize] = {0};
SLANG_RETURN_ON_FAIL(stream->write(trailing, remainingSize));
}
}
- default: break;
+ default: break;
}
// Next
chunk = chunk->m_next;
}
-
+
return SLANG_OK;
}
-/* static */SlangResult RiffUtil::write(RiffContainer* container, Stream* stream)
+/* static */ SlangResult RiffUtil::write(RiffContainer* container, Stream* stream)
{
return write(container->getRoot(), true, stream);
}
-/* static */SlangResult RiffUtil::read(Stream* stream, RiffContainer& outContainer)
+/* static */ SlangResult RiffUtil::read(Stream* stream, RiffContainer& outContainer)
{
typedef RiffContainer::ScopeChunk ScopeChunk;
outContainer.reset();
@@ -333,7 +352,7 @@ struct DumpVisitor : public RiffContainer::Visitor
const size_t padSize = getPadSize(header.chunk.size);
// Subtract the size of this chunk from remaining of the current chunk
- remaining -= sizeof(RiffHeader) + padSize;
+ remaining -= sizeof(RiffHeader) + padSize;
// Push it, for when we hit the end
remainingStack.add(remaining);
@@ -347,11 +366,12 @@ struct DumpVisitor : public RiffContainer::Visitor
{
ScopeChunk scopeChunk(&outContainer, Chunk::Kind::Data, header.chunk.type);
RiffContainer::Data* data = outContainer.addData();
-
+
outContainer.setPayload(data, nullptr, header.chunk.size);
size_t readSize;
- SLANG_RETURN_ON_FAIL(readPayload(stream, header.chunk.size, data->getPayload(), readSize));
+ SLANG_RETURN_ON_FAIL(
+ readPayload(stream, header.chunk.size, data->getPayload(), readSize));
// All read sizes must end up aligned
SLANG_ASSERT((readSize & kRiffPadMask) == 0);
@@ -371,11 +391,11 @@ SlangResult RiffContainer::Chunk::visit(Visitor* visitor)
{
switch (m_kind)
{
- case Kind::Data:
+ case Kind::Data:
{
return visitor->handleData(static_cast<DataChunk*>(this));
}
- case Kind::List:
+ case Kind::List:
{
auto list = static_cast<ListChunk*>(this);
SLANG_RETURN_ON_FAIL(visitor->enterList(list));
@@ -391,7 +411,7 @@ SlangResult RiffContainer::Chunk::visit(Visitor* visitor)
SLANG_RETURN_ON_FAIL(visitor->leaveList(list));
return SLANG_OK;
}
- default: return SLANG_FAIL;
+ default: return SLANG_FAIL;
}
}
@@ -399,11 +419,11 @@ SlangResult RiffContainer::Chunk::visitPreOrder(VisitorCallback callback, void*
{
switch (m_kind)
{
- case Kind::Data:
+ case Kind::Data:
{
return callback(this, data);
}
- case Kind::List:
+ case Kind::List:
{
auto list = static_cast<ListChunk*>(this);
// Do this containing node first
@@ -418,7 +438,7 @@ SlangResult RiffContainer::Chunk::visitPreOrder(VisitorCallback callback, void*
}
return SLANG_OK;
}
- default: return SLANG_FAIL;
+ default: return SLANG_FAIL;
}
}
@@ -426,11 +446,11 @@ SlangResult RiffContainer::Chunk::visitPostOrder(VisitorCallback callback, void*
{
switch (m_kind)
{
- case Kind::Data:
+ case Kind::Data:
{
return callback(this, data);
}
- case Kind::List:
+ case Kind::List:
{
auto list = static_cast<ListChunk*>(this);
@@ -445,7 +465,7 @@ SlangResult RiffContainer::Chunk::visitPostOrder(VisitorCallback callback, void*
SLANG_RETURN_ON_FAIL(callback(this, data));
return SLANG_OK;
}
- default: return SLANG_FAIL;
+ default: return SLANG_FAIL;
}
}
@@ -453,15 +473,15 @@ size_t RiffContainer::Chunk::calcPayloadSize()
{
switch (m_kind)
{
- case Kind::Data: return static_cast<DataChunk*>(this)->calcPayloadSize();
- case Kind::List: return static_cast<ListChunk*>(this)->calcPayloadSize();
- default: return 0;
+ case Kind::Data: return static_cast<DataChunk*>(this)->calcPayloadSize();
+ case Kind::List: return static_cast<ListChunk*>(this)->calcPayloadSize();
+ default: return 0;
}
}
RiffContainer::Data* RiffContainer::Chunk::getSingleData() const
{
- return (m_kind == Kind::Data) ? static_cast<const DataChunk*>(this)->getSingleData(): nullptr;
+ return (m_kind == Kind::Data) ? static_cast<const DataChunk*>(this)->getSingleData() : nullptr;
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!! RiffContainer::ListChunk !!!!!!!!!!!!!!!!!!!!!!
@@ -582,7 +602,7 @@ static RiffContainer::ListChunk* _findListRec(RiffContainer::ListChunk* list, Fo
return nullptr;
}
-/* static */RiffContainer::ListChunk* RiffContainer::ListChunk::findListRec(FourCC subType)
+/* static */ RiffContainer::ListChunk* RiffContainer::ListChunk::findListRec(FourCC subType)
{
return (getSubType() == subType) ? this : _findListRec(this, subType);
}
@@ -683,8 +703,8 @@ bool RiffContainer::DataChunk::isEqual(const void* inData, size_t count) const
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RiffContainer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-RiffContainer::RiffContainer() :
- m_arena(4096)
+RiffContainer::RiffContainer()
+ : m_arena(4096)
{
m_rootList = nullptr;
m_listChunk = nullptr;
@@ -723,7 +743,8 @@ void RiffContainer::_addChunk(Chunk* chunk)
if (m_listChunk)
{
chunk->m_parent = m_listChunk;
- Chunk*& next = m_listChunk->m_endChunk ? m_listChunk->m_endChunk->m_next : m_listChunk->m_containedChunks;
+ Chunk*& next = m_listChunk->m_endChunk ? m_listChunk->m_endChunk->m_next
+ : m_listChunk->m_containedChunks;
SLANG_ASSERT(next == nullptr);
next = chunk;
m_listChunk->m_endChunk = chunk;
@@ -736,9 +757,10 @@ void RiffContainer::startChunk(Chunk::Kind kind, FourCC fourCC)
switch (kind)
{
- case Chunk::Kind::Data:
+ case Chunk::Kind::Data:
{
- // We can only start a data chunk if we are in a container, and we can't already be in data chunk
+ // We can only start a data chunk if we are in a container, and we can't already be in
+ // data chunk
SLANG_ASSERT(m_listChunk && m_dataChunk == nullptr);
DataChunk* chunk = _newDataChunk(fourCC);
@@ -746,7 +768,7 @@ void RiffContainer::startChunk(Chunk::Kind kind, FourCC fourCC)
m_dataChunk = chunk;
break;
}
- case Chunk::Kind::List:
+ case Chunk::Kind::List:
{
// We can't be in a data chunk
SLANG_ASSERT(m_dataChunk == nullptr);
@@ -771,7 +793,7 @@ void RiffContainer::endChunk()
{
size_t chunkPayloadSize;
- // The chunk we are popping
+ // The chunk we are popping
// Only keep track of this in debug builds
[[maybe_unused]] Chunk* chunk = nullptr;
@@ -782,7 +804,7 @@ void RiffContainer::endChunk()
parent = m_dataChunk->m_parent;
chunkPayloadSize = m_dataChunk->m_payloadSize;
-
+
m_dataChunk = nullptr;
}
else
@@ -824,7 +846,7 @@ void RiffContainer::setPayload(Data* data, const void* payload, size_t size)
// Add current chunks data
m_dataChunk->m_payloadSize += size;
-
+
data->m_ownership = Ownership::Arena;
data->m_size = size;
@@ -901,7 +923,7 @@ RiffContainer::Data* RiffContainer::makeSingleData(DataChunk* dataChunk)
{
Data* data = dataChunk->m_dataList;
-
+
// Okay lets combine all into one block
const size_t payloadSize = dataChunk->calcPayloadSize();
@@ -932,7 +954,7 @@ void RiffContainer::write(const void* inData, size_t size)
{
uint8_t* end = ((uint8_t*)endData->m_payload) + endData->m_size;
// See if can just add to end of current data
- if ( end == m_arena.getCursor() && m_arena.allocateCurrentUnaligned(size))
+ if (end == m_arena.getCursor() && m_arena.allocateCurrentUnaligned(size))
{
::memcpy(end, inData, size);
endData->m_size += size;
@@ -953,7 +975,7 @@ static SlangResult _isChunkOk(RiffContainer::Chunk* chunk, void* data)
return chunk->calcPayloadSize() == chunk->m_payloadSize ? SLANG_OK : SLANG_FAIL;
}
-/* static */bool RiffContainer::isChunkOk(Chunk* chunk)
+/* static */ bool RiffContainer::isChunkOk(Chunk* chunk)
{
return SLANG_SUCCEEDED(chunk->visitPostOrder(&_isChunkOk, nullptr));
}
@@ -965,11 +987,10 @@ static SlangResult _calcAndSetSize(RiffContainer::Chunk* chunk, void* data)
return SLANG_OK;
}
-/* static */void RiffContainer::calcAndSetSize(Chunk* chunk)
+/* static */ void RiffContainer::calcAndSetSize(Chunk* chunk)
{
chunk->visitPostOrder(&_calcAndSetSize, nullptr);
}
-
-}
+} // namespace Slang
diff --git a/source/core/slang-riff.h b/source/core/slang-riff.h
index 3a964df2d..1e2c883b9 100644
--- a/source/core/slang-riff.h
+++ b/source/core/slang-riff.h
@@ -2,10 +2,10 @@
#define SLANG_RIFF_H
#include "slang-basic.h"
-#include "slang-stream.h"
#include "slang-memory-arena.h"
-#include "slang-writer.h"
#include "slang-semantic-version.h"
+#include "slang-stream.h"
+#include "slang-writer.h"
namespace Slang
{
@@ -16,27 +16,30 @@ namespace Slang
typedef uint32_t FourCC;
-/* Use of macros to construct and extract from FourCC means the FourCC ordering can be fixed for endian differences. */
+/* Use of macros to construct and extract from FourCC means the FourCC ordering can be fixed for
+ * endian differences. */
-#if SLANG_LITTLE_ENDIAN
+#if SLANG_LITTLE_ENDIAN
-#define SLANG_FOUR_CC(c0, c1, c2, c3) ((FourCC(c0) << 0) | (FourCC(c1) << 8) | (FourCC(c2) << 16) | (FourCC(c3) << 24))
+#define SLANG_FOUR_CC(c0, c1, c2, c3) \
+ ((FourCC(c0) << 0) | (FourCC(c1) << 8) | (FourCC(c2) << 16) | (FourCC(c3) << 24))
#define SLANG_FOUR_CC_GET_FIRST_CHAR(x) char((x) & 0xff)
#define SLANG_FOUR_CC_REPLACE_FIRST_CHAR(x, c) (((x) & 0xffffff00) | FourCC(c))
#else
-#define SLANG_FOUR_CC(c0, c1, c2, c3) ((FourCC(c0) << 24) | (FourCC(c1) << 16) | (FourCC(c2) << 8) | (FourCC(c3) << 0))
+#define SLANG_FOUR_CC(c0, c1, c2, c3) \
+ ((FourCC(c0) << 24) | (FourCC(c1) << 16) | (FourCC(c2) << 8) | (FourCC(c3) << 0))
#define SLANG_FOUR_CC_GET_FIRST_CHAR(x) char((x) >> 24)
#define SLANG_FOUR_CC_REPLACE_FIRST_CHAR(x, c) (((x) & 0x00ffffff) | (FourCC(c) << 24))
#endif
-enum
+enum
{
- kRiffPadSize = 2, ///< We only align to 2 bytes
+ kRiffPadSize = 2, ///< We only align to 2 bytes
kRiffPadMask = kRiffPadSize - 1,
};
@@ -45,8 +48,9 @@ typedef int RiffHashCode;
struct RiffHeader
{
- FourCC type; ///< The FourCC code that identifies this chunk
- uint32_t size; ///< Size does *NOT* include the riff chunk size. The size can be byte sized, but on storage it will always be treated as aligned up by 4.
+ FourCC type; ///< The FourCC code that identifies this chunk
+ uint32_t size; ///< Size does *NOT* include the riff chunk size. The size can be byte sized, but
+ ///< on storage it will always be treated as aligned up by 4.
};
struct RiffListHeader
@@ -58,35 +62,39 @@ struct RiffListHeader
struct RiffFourCC
{
- /// A 'riff' is the high level file container. It is followed by a subtype and then the contained chunks.
- static const FourCC kRiff = SLANG_FOUR_CC('R', 'I', 'F', 'F');
- /// A list is the same as a 'riff' except can be placed anywhere in hierarchy.
- static const FourCC kList = SLANG_FOUR_CC('L', 'I', 'S', 'T');
+ /// A 'riff' is the high level file container. It is followed by a subtype and then the
+ /// contained chunks.
+ static const FourCC kRiff = SLANG_FOUR_CC('R', 'I', 'F', 'F');
+ /// A list is the same as a 'riff' except can be placed anywhere in hierarchy.
+ static const FourCC kList = SLANG_FOUR_CC('L', 'I', 'S', 'T');
+
private:
RiffFourCC() = delete;
};
// Follows semantic version rules
// https://semver.org/
-//
+//
// major.minor.patch
-// Patch versions indicate a change.
-// Minor means a change that is backwards compatible with previous minor versions. A step in minor and/or major zeros patch.
-// Major means a non compatible change. A step in major, zeros minor and patch.
+// Patch versions indicate a change.
+// Minor means a change that is backwards compatible with previous minor versions. A step in minor
+// and/or major zeros patch. Major means a non compatible change. A step in major, zeros minor and
+// patch.
struct RiffSemanticVersion
{
typedef RiffSemanticVersion ThisType;
typedef uint32_t RawType;
- /// ==
+ /// ==
bool operator==(const ThisType& rhs) const { return m_raw == rhs.m_raw; }
bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
-
- /// A patch change indices a different version but does not change the compatibility of the format
+
+ /// A patch change indices a different version but does not change the compatibility of the
+ /// format
int getPatch() const { return m_raw & 0xff; }
- /// A minor change implies a format change that is backwards compatible
+ /// A minor change implies a format change that is backwards compatible
int getMinor() const { return (m_raw >> 8) & 0xff; }
- /// A major change is binary incompatible by default
+ /// A major change is binary incompatible by default
int getMajor() const { return (m_raw >> 16); }
SemanticVersion asSemanticVersion() const
@@ -108,18 +116,25 @@ struct RiffSemanticVersion
return version;
}
- static RiffSemanticVersion make(int major, int minor, int patch) { return makeFromRaw(makeRaw(major, minor, patch)); }
- static RiffSemanticVersion make(const SemanticVersion& in) { return makeFromRaw(makeRaw(in.m_major, in.m_minor, in.m_patch)); }
+ static RiffSemanticVersion make(int major, int minor, int patch)
+ {
+ return makeFromRaw(makeRaw(major, minor, patch));
+ }
+ static RiffSemanticVersion make(const SemanticVersion& in)
+ {
+ return makeFromRaw(makeRaw(in.m_major, in.m_minor, in.m_patch));
+ }
- /// True if the read version is compatible with the current version, based on semantic rules.
+ /// True if the read version is compatible with the current version, based on semantic rules.
static bool areCompatible(const ThisType& currentVersion, const ThisType& readVersion)
{
const RawType currentRaw = currentVersion.m_raw;
const RawType readRaw = readVersion.m_raw;
// Must have same major version.
- // For minor version, the read version must be less than or equal.
- return ((currentRaw & 0xffff0000) == (readRaw & 0xffff0000)) && ((currentRaw & 0xff00) >= (readRaw & 0xff00));
+ // For minor version, the read version must be less than or equal.
+ return ((currentRaw & 0xffff0000) == (readRaw & 0xffff0000)) &&
+ ((currentRaw & 0xff00) >= (readRaw & 0xff00));
}
RawType m_raw;
@@ -129,7 +144,7 @@ struct RiffSemanticVersion
class RiffReadHelper
{
public:
- template <typename T>
+ template<typename T>
SlangResult read(T& out)
{
if (m_cur + sizeof(T) > m_end)
@@ -143,15 +158,13 @@ public:
return SLANG_OK;
}
- /// Get the data
+ /// Get the data
const uint8_t* getData() const { return m_cur; }
- /// Get the remaining size
+ /// Get the remaining size
size_t getRemainingSize() const { return size_t(m_end - m_cur); }
- RiffReadHelper(const uint8_t* data, size_t size):
- m_start(data),
- m_end(data + size),
- m_cur(data)
+ RiffReadHelper(const uint8_t* data, size_t size)
+ : m_start(data), m_end(data + size), m_cur(data)
{
}
@@ -176,37 +189,38 @@ protected:
With the data held in memory allows for adding or removing chunks at will.
A future implementation does not necessarily have to be backed by memory when construction,
-as data could be written to stream, and the chunk sizes written by seeking back over the file and setting the value.
+as data could be written to stream, and the chunk sizes written by seeking back over the file and
+setting the value.
-In normal usage the chunk sizes are calculated during construction. If the structure is changed, the sizes may
-need to be recalculated, before serialization.
+In normal usage the chunk sizes are calculated during construction. If the structure is changed, the
+sizes may need to be recalculated, before serialization.
*/
class RiffContainer
{
public:
- // This alignment is only made for arena based allocations.
- // For external blocks it's client code to have appropriate alignment.
- // This is needed because when reading a RiffContainer, all allocation is arena based, and
- // if the payload contains 8 byte aligned data, the overall payload needs to be 8 byte aligned.
+ // This alignment is only made for arena based allocations.
+ // For external blocks it's client code to have appropriate alignment.
+ // This is needed because when reading a RiffContainer, all allocation is arena based, and
+ // if the payload contains 8 byte aligned data, the overall payload needs to be 8 byte aligned.
static const size_t kPayloadMinAlignment = 8;
enum class Ownership
{
- Uninitialized, ///< Doesn't contain anything
- NotOwned, ///< It's not owned by the container
- Arena, ///< It's owned and allocated on the arena
- Owned, ///< It's owned, but wasn't allocated on the arena
+ Uninitialized, ///< Doesn't contain anything
+ NotOwned, ///< It's not owned by the container
+ Arena, ///< It's owned and allocated on the arena
+ Owned, ///< It's owned, but wasn't allocated on the arena
};
struct Data
{
- /// Get the payload
+ /// Get the payload
void* getPayload() { return m_payload; }
- /// Get the end pointer
+ /// Get the end pointer
void* getPayloadEnd() { return (void*)((uint8_t*)m_payload + m_size); }
- /// Get the size of the payload
+ /// Get the size of the payload
size_t getSize() const { return m_size; }
- /// Get the ownership of the data held in the payload
+ /// Get the ownership of the data held in the payload
Ownership getOwnership() const { return m_ownership; }
void init()
@@ -217,24 +231,25 @@ public:
m_payload = nullptr;
}
- Ownership m_ownership; ///< Stores the ownership of the payload
- size_t m_size; ///< The size of the payload
- void* m_payload; ///< The payload
- Data* m_next; ///< The next Data block in the list
+ Ownership m_ownership; ///< Stores the ownership of the payload
+ size_t m_size; ///< The size of the payload
+ void* m_payload; ///< The payload
+ Data* m_next; ///< The next Data block in the list
};
struct Chunk;
struct ListChunk;
struct DataChunk;
- typedef SlangResult(*VisitorCallback)(Chunk* chunk, void* data);
-
+ typedef SlangResult (*VisitorCallback)(Chunk* chunk, void* data);
+
class Visitor;
struct Chunk
{
enum class Kind
{
- List, ///< Strictly speaking this can be a 'LIST' or a 'RIFF' as they have the same structure
+ List, ///< Strictly speaking this can be a 'LIST' or a 'RIFF' as they have the same
+ ///< structure
Data,
};
@@ -251,23 +266,26 @@ public:
SlangResult visitPostOrder(VisitorCallback callback, void* data);
SlangResult visitPreOrder(VisitorCallback callback, void* data);
- /// Returns a single data chunk
+ /// Returns a single data chunk
Data* getSingleData() const;
- /// Calculate the payload size
+ /// Calculate the payload size
size_t calcPayloadSize();
- Kind m_kind; ///< Kind of chunk
- FourCC m_fourCC; ///< The chunk type for data, or the sub type for a List (riff/list)
- size_t m_payloadSize; ///< The payload size (ie does NOT include RiffChunk header).
- Chunk* m_next; ///< Next chunk in this list
- ListChunk* m_parent; ///< The chunk this belongs to
+ Kind m_kind; ///< Kind of chunk
+ FourCC m_fourCC; ///< The chunk type for data, or the sub type for a List (riff/list)
+ size_t m_payloadSize; ///< The payload size (ie does NOT include RiffChunk header).
+ Chunk* m_next; ///< Next chunk in this list
+ ListChunk* m_parent; ///< The chunk this belongs to
};
struct ListChunk : public Chunk
{
typedef Chunk Super;
- SLANG_FORCE_INLINE static bool isType(const Chunk* chunk) { return chunk->m_kind == Kind::List; }
+ SLANG_FORCE_INLINE static bool isType(const Chunk* chunk)
+ {
+ return chunk->m_kind == Kind::List;
+ }
void init(FourCC subType)
{
@@ -278,61 +296,68 @@ public:
m_payloadSize = uint32_t(sizeof(RiffListHeader) - sizeof(RiffHeader));
}
- /// Finds chunk (list or data) that matches type. For List/Riff, type is the subtype
+ /// Finds chunk (list or data) that matches type. For List/Riff, type is the subtype
Chunk* findContained(FourCC type) const;
void* findContainedData(FourCC type, size_t minSize) const;
ListChunk* findContainedList(FourCC type);
- /// Finds the contained data. NOTE! Assumes that there is only as single data block, and will return nullptr if there is not
+ /// Finds the contained data. NOTE! Assumes that there is only as single data block, and
+ /// will return nullptr if there is not
Data* findContainedData(FourCC type) const;
- template <typename T>
- T* findContainedData(FourCC type) const { return (T*)findContainedData(type, sizeof(T)); }
+ template<typename T>
+ T* findContainedData(FourCC type) const
+ {
+ return (T*)findContainedData(type, sizeof(T));
+ }
- /// Find all contained that match the type
+ /// Find all contained that match the type
void findContained(FourCC type, List<ListChunk*>& out);
- /// Find all contained that match the type
+ /// Find all contained that match the type
void findContained(FourCC type, List<DataChunk*>& out);
- /// Find the list (including self) that matches subtype recursively
+ /// Find the list (including self) that matches subtype recursively
ListChunk* findListRec(FourCC subType);
- /// NOTE! Assumes all contained chunks have correct payload sizes
+ /// NOTE! Assumes all contained chunks have correct payload sizes
size_t calcPayloadSize();
- /// Get the sub type
+ /// Get the sub type
FourCC getSubType() const { return m_fourCC; }
- /// A singly linked list of contained chunks directly contained in this chunk
+ /// A singly linked list of contained chunks directly contained in this chunk
Chunk* getFirstContainedChunk() const { return m_containedChunks; }
- Chunk* m_containedChunks; ///< The contained chunks
- Chunk* m_endChunk; ///< The last chunk (only set when pushed, and used when popped)
+ Chunk* m_containedChunks; ///< The contained chunks
+ Chunk* m_endChunk; ///< The last chunk (only set when pushed, and used when popped)
};
struct DataChunk : public Chunk
{
typedef Chunk Super;
- SLANG_FORCE_INLINE static bool isType(const Chunk* chunk) { return chunk->m_kind == Kind::Data; }
+ SLANG_FORCE_INLINE static bool isType(const Chunk* chunk)
+ {
+ return chunk->m_kind == Kind::Data;
+ }
- /// Calculate a hash (not necessarily very fast)
+ /// Calculate a hash (not necessarily very fast)
RiffHashCode calcHash() const;
- /// Calculate the payload size
+ /// Calculate the payload size
size_t calcPayloadSize() const;
- /// Copy the payload to dst. Dst must be at least the payload size.
+ /// Copy the payload to dst. Dst must be at least the payload size.
void getPayload(void* dst) const;
- /// True if payloads contents is equal to data
+ /// True if payloads contents is equal to data
bool isEqual(const void* data, size_t count) const;
- /// Get single data payload.
+ /// Get single data payload.
Data* getSingleData() const;
- /// Return as read helper
+ /// Return as read helper
RiffReadHelper asReadHelper() const;
void init(FourCC fourCC)
@@ -342,22 +367,20 @@ public:
m_endData = nullptr;
}
- Data* m_dataList; ///< List of 0 or more data items
- Data* m_endData; ///< The last data point
+ Data* m_dataList; ///< List of 0 or more data items
+ Data* m_endData; ///< The last data point
};
class ScopeChunk
{
public:
- ScopeChunk(RiffContainer* container, Chunk::Kind kind, FourCC fourCC) :
- m_container(container)
+ ScopeChunk(RiffContainer* container, Chunk::Kind kind, FourCC fourCC)
+ : m_container(container)
{
container->startChunk(kind, fourCC);
}
- ~ScopeChunk()
- {
- m_container->endChunk();
- }
+ ~ScopeChunk() { m_container->endChunk(); }
+
private:
RiffContainer* m_container;
};
@@ -371,54 +394,61 @@ public:
};
- /// Add a complete data chunk
+ /// Add a complete data chunk
void addDataChunk(FourCC dataFourCC, const void* data, size_t dataSizeInBytes);
- /// Start a chunk
+ /// Start a chunk
void startChunk(Chunk::Kind kind, FourCC type);
- /// Write data into a chunk (can only be inside a Kind::Data)
+ /// Write data into a chunk (can only be inside a Kind::Data)
void write(const void* data, size_t size);
- /// Adds an empty data block
+ /// Adds an empty data block
Data* addData();
- /// Set the payload on a data. Payload can be passed as nullptr, if it is no memory will be copied.
+ /// Set the payload on a data. Payload can be passed as nullptr, if it is no memory will be
+ /// copied.
void setPayload(Data* data, const void* payload, size_t size);
- /// Move ownership to.
- /// NOTE! The payload *must* be deallocatable via 'free'
+ /// Move ownership to.
+ /// NOTE! The payload *must* be deallocatable via 'free'
void moveOwned(Data* data, void* payload, size_t size);
- /// Move unowned. The payload scope must last longer than the RiffContainer
+ /// Move unowned. The payload scope must last longer than the RiffContainer
void setUnowned(Data* data, void* payload, size_t size);
- /// End a chunk
+ /// End a chunk
void endChunk();
- /// Get the root
+ /// Get the root
ListChunk* getRoot() const { return m_rootList; }
- /// Get the current chunk
- Chunk* getCurrentChunk() { return m_dataChunk ? static_cast<Chunk*>(m_dataChunk) : static_cast<Chunk*>(m_listChunk); }
+ /// Get the current chunk
+ Chunk* getCurrentChunk()
+ {
+ return m_dataChunk ? static_cast<Chunk*>(m_dataChunk) : static_cast<Chunk*>(m_listChunk);
+ }
- /// Reset the container
+ /// Reset the container
void reset();
- /// true if has a root container, and nothing remains open
- bool isFullyConstructed() { return m_rootList && m_listChunk == nullptr && m_dataChunk == nullptr; }
+ /// true if has a root container, and nothing remains open
+ bool isFullyConstructed()
+ {
+ return m_rootList && m_listChunk == nullptr && m_dataChunk == nullptr;
+ }
- /// Makes a data chunk contain a single contiguous data block
+ /// Makes a data chunk contain a single contiguous data block
Data* makeSingleData(DataChunk* dataChunk);
- /// Get the memory arena that is backing the storage of data
+ /// Get the memory arena that is backing the storage of data
MemoryArena& getMemoryArena() { return m_arena; }
- /// The if the list and sublists appear correct
+ /// The if the list and sublists appear correct
static bool isChunkOk(Chunk* chunk);
- /// Traverses over chunk hierarchy and sets the sizes
+ /// Traverses over chunk hierarchy and sets the sizes
static void calcAndSetSize(Chunk* chunk);
- /// Ctor
+ /// Ctor
RiffContainer();
protected:
@@ -426,25 +456,26 @@ protected:
ListChunk* _newListChunk(FourCC subType);
DataChunk* _newDataChunk(FourCC type);
- ListChunk* m_rootList; ///< Root list
+ ListChunk* m_rootList; ///< Root list
ListChunk* m_listChunk;
DataChunk* m_dataChunk;
- MemoryArena m_arena; ///< Can be used to use other owned blocks
+ MemoryArena m_arena; ///< Can be used to use other owned blocks
};
// -----------------------------------------------------------------------------
-template <typename T>
+template<typename T>
T* as(RiffContainer::Chunk* chunk)
{
return chunk && T::isType(chunk) ? static_cast<T*>(chunk) : nullptr;
}
// -----------------------------------------------------------------------------
-template <typename T>
+template<typename T>
T* as(RiffContainer::Chunk* chunk, FourCC fourCC)
{
- return chunk && chunk->m_fourCC == fourCC && T::isType(chunk) ? static_cast<T*>(chunk) : nullptr;
+ return chunk && chunk->m_fourCC == fourCC && T::isType(chunk) ? static_cast<T*>(chunk)
+ : nullptr;
}
struct RiffUtil
@@ -459,32 +490,44 @@ struct RiffUtil
static SlangResult readChunk(Stream* stream, RiffHeader& outChunk);
- static SlangResult writeData(const RiffHeader* header, size_t headerSize, const void* payload, size_t payloadSize, Stream* out);
- static SlangResult readData(Stream* stream, RiffHeader* outHeader, size_t headerSize, List<uint8_t>& data);
+ static SlangResult writeData(
+ const RiffHeader* header,
+ size_t headerSize,
+ const void* payload,
+ size_t payloadSize,
+ Stream* out);
+ static SlangResult readData(
+ Stream* stream,
+ RiffHeader* outHeader,
+ size_t headerSize,
+ List<uint8_t>& data);
static SlangResult readPayload(Stream* stream, size_t size, void* outData, size_t& outReadSize);
- /// Read a header. Handles special case of list/riff types
+ /// Read a header. Handles special case of list/riff types
static SlangResult readHeader(Stream* stream, RiffListHeader& outHeader);
- /// True if the type is a container type
- static bool isListType(FourCC type) { return type == RiffFourCC::kRiff || type == RiffFourCC::kList; }
+ /// True if the type is a container type
+ static bool isListType(FourCC type)
+ {
+ return type == RiffFourCC::kRiff || type == RiffFourCC::kList;
+ }
- /// Dump the chunk structure
+ /// Dump the chunk structure
static void dump(Chunk* chunk, WriterHelper writer);
- /// Get the size taking into account padding
+ /// Get the size taking into account padding
static size_t getPadSize(size_t in) { return (in + kRiffPadMask) & ~size_t(kRiffPadMask); }
- /// Write a chunk list and contents to a stream
+ /// Write a chunk list and contents to a stream
static SlangResult write(ListChunk* listChunk, bool isRoot, Stream* stream);
- /// Write a container to the stream
+ /// Write a container to the stream
static SlangResult write(RiffContainer* container, Stream* stream);
- /// Read the stream into the container
+ /// Read the stream into the container
static SlangResult read(Stream* stream, RiffContainer& outContainer);
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-rtti-info.cpp b/source/core/slang-rtti-info.cpp
index de0460082..9ca1c19b6 100644
--- a/source/core/slang-rtti-info.cpp
+++ b/source/core/slang-rtti-info.cpp
@@ -1,19 +1,26 @@
#include "slang-rtti-info.h"
#include "slang-com-helper.h"
-
#include "slang-rtti-util.h"
#include <mutex>
-namespace Slang {
+namespace Slang
+{
-#define SLANG_RTTI_INFO_INVALID(name) RttiInfo{RttiInfo::Kind::Invalid, 0, 0}
-#define SLANG_RTTI_INFO_BASIC(name, type) \
- RttiInfo{RttiInfo::Kind::name, RttiInfo::AlignmentType(SLANG_ALIGN_OF(type)), RttiInfo::SizeType(sizeof(type))}
+#define SLANG_RTTI_INFO_INVALID(name) \
+ RttiInfo \
+ { \
+ RttiInfo::Kind::Invalid, 0, 0 \
+ }
+#define SLANG_RTTI_INFO_BASIC(name, type) \
+ RttiInfo \
+ { \
+ RttiInfo::Kind::name, RttiInfo::AlignmentType(SLANG_ALIGN_OF(type)), \
+ RttiInfo::SizeType(sizeof(type)) \
+ }
-/* static */const RttiInfo RttiInfo::g_basicTypes[Index(Kind::CountOf)] =
-{
+/* static */ const RttiInfo RttiInfo::g_basicTypes[Index(Kind::CountOf)] = {
SLANG_RTTI_INFO_INVALID(Invalid),
SLANG_RTTI_INFO_BASIC(I32, int32_t),
SLANG_RTTI_INFO_BASIC(U32, uint32_t),
@@ -54,26 +61,27 @@ struct RttiInfoManager
}
protected:
- RttiInfoManager() :
- m_arena(1024)
+ RttiInfoManager()
+ : m_arena(1024)
{
}
- std::recursive_mutex m_mutex; ///< We need a mutex to guard access to m_arena
+ std::recursive_mutex m_mutex; ///< We need a mutex to guard access to m_arena
MemoryArena m_arena;
};
-/* static */void* RttiInfo::allocate(size_t size)
+/* static */ void* RttiInfo::allocate(size_t size)
{
return RttiInfoManager::getSingleton().allocate(size);
}
-/* static */void RttiInfo::deallocateAll()
+/* static */ void RttiInfo::deallocateAll()
{
return RttiInfoManager::getSingleton().deallocateAll();
}
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructRttiBuilder !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructRttiBuilder !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
static void _appendFixedArray(const FixedArrayRttiInfo* inFixedArray, StringBuilder& out)
{
@@ -97,27 +105,27 @@ static void _appendFixedArray(const FixedArrayRttiInfo* inFixedArray, StringBuil
}
}
-/* static */void RttiInfo::append(const RttiInfo* info, StringBuilder& out)
+/* static */ void RttiInfo::append(const RttiInfo* info, StringBuilder& out)
{
switch (info->m_kind)
{
- case RttiInfo::Kind::I32: out << "int32_t"; break;
- case RttiInfo::Kind::U32: out << "uint32_t"; break;
- case RttiInfo::Kind::I64: out << "int64_t"; break;
- case RttiInfo::Kind::U64: out << "uint64_t"; break;
- case RttiInfo::Kind::F32: out << "float"; break;
- case RttiInfo::Kind::F64: out << "double"; break;
- case RttiInfo::Kind::Bool: out << "bool"; break;
- case RttiInfo::Kind::String: out << "String"; break;
- case RttiInfo::Kind::UnownedStringSlice: out << "UnownedStringSlice"; break;
- case RttiInfo::Kind::Ptr:
+ case RttiInfo::Kind::I32: out << "int32_t"; break;
+ case RttiInfo::Kind::U32: out << "uint32_t"; break;
+ case RttiInfo::Kind::I64: out << "int64_t"; break;
+ case RttiInfo::Kind::U64: out << "uint64_t"; break;
+ case RttiInfo::Kind::F32: out << "float"; break;
+ case RttiInfo::Kind::F64: out << "double"; break;
+ case RttiInfo::Kind::Bool: out << "bool"; break;
+ case RttiInfo::Kind::String: out << "String"; break;
+ case RttiInfo::Kind::UnownedStringSlice: out << "UnownedStringSlice"; break;
+ case RttiInfo::Kind::Ptr:
{
const PtrRttiInfo* ptrRttiInfo = static_cast<const PtrRttiInfo*>(info);
append(ptrRttiInfo->m_targetType, out);
out << "*";
break;
}
- case RttiInfo::Kind::RefPtr:
+ case RttiInfo::Kind::RefPtr:
{
const RefPtrRttiInfo* ptrRttiInfo = static_cast<const RefPtrRttiInfo*>(info);
out << "RefPtr<";
@@ -125,13 +133,13 @@ static void _appendFixedArray(const FixedArrayRttiInfo* inFixedArray, StringBuil
out << ">";
break;
}
- case RttiInfo::Kind::FixedArray:
+ case RttiInfo::Kind::FixedArray:
{
const FixedArrayRttiInfo* arrayRttiInfo = static_cast<const FixedArrayRttiInfo*>(info);
_appendFixedArray(arrayRttiInfo, out);
break;
}
- case RttiInfo::Kind::List:
+ case RttiInfo::Kind::List:
{
const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(info);
out << "List<";
@@ -139,9 +147,10 @@ static void _appendFixedArray(const FixedArrayRttiInfo* inFixedArray, StringBuil
out << ">";
break;
}
- case RttiInfo::Kind::Dictionary:
+ case RttiInfo::Kind::Dictionary:
{
- const DictionaryRttiInfo* dictionaryRttiInfo = static_cast<const DictionaryRttiInfo*>(info);
+ const DictionaryRttiInfo* dictionaryRttiInfo =
+ static_cast<const DictionaryRttiInfo*>(info);
out << "Dictionary<";
append(dictionaryRttiInfo->m_keyType, out);
@@ -150,7 +159,7 @@ static void _appendFixedArray(const FixedArrayRttiInfo* inFixedArray, StringBuil
out << ">";
break;
}
- default:
+ default:
{
if (info->isNamed())
{
@@ -165,7 +174,8 @@ static void _appendFixedArray(const FixedArrayRttiInfo* inFixedArray, StringBuil
}
}
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructRttiBuilder !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructRttiBuilder !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
void StructRttiBuilder::_init(const char* name, const StructRttiInfo* super, const Byte* base)
{
@@ -183,7 +193,8 @@ StructRttiInfo StructRttiBuilder::make()
if (fieldCount)
{
- StructRttiInfo::Field* dstFields = (StructRttiInfo::Field*)RttiInfo::allocate(sizeof(StructRttiInfo::Field) * fieldCount);
+ StructRttiInfo::Field* dstFields =
+ (StructRttiInfo::Field*)RttiInfo::allocate(sizeof(StructRttiInfo::Field) * fieldCount);
::memcpy(dstFields, m_fields.getBuffer(), sizeof(StructRttiInfo::Field) * fieldCount);
m_rttiInfo.m_fields = dstFields;
@@ -193,7 +204,8 @@ StructRttiInfo StructRttiBuilder::make()
return m_rttiInfo;
}
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RttiTypeFuncsMap !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RttiTypeFuncsMap !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
RttiTypeFuncs RttiTypeFuncsMap::getFuncsForType(const RttiInfo* rttiInfo)
{
@@ -215,7 +227,7 @@ void RttiTypeFuncsMap::add(const RttiInfo* rttiInfo, const RttiTypeFuncs& funcs)
{
if (auto funcsPtr = m_map.tryGetValueOrAdd(rttiInfo, funcs))
{
- // If there are funcs set, they aren't valid otherwise this would be
+ // If there are funcs set, they aren't valid otherwise this would be
// replacing, so assert on that scenario.
SLANG_ASSERT(!funcsPtr->isValid());
diff --git a/source/core/slang-rtti-info.h b/source/core/slang-rtti-info.h
index a7262e50f..01c042511 100644
--- a/source/core/slang-rtti-info.h
+++ b/source/core/slang-rtti-info.h
@@ -2,25 +2,32 @@
#define SLANG_CORE_RTTI_INFO_H
#include "slang-basic.h"
-#include "slang-memory-arena.h"
-
-#include "slang-list.h"
#include "slang-dictionary.h"
+#include "slang-list.h"
+#include "slang-memory-arena.h"
-namespace Slang {
+namespace Slang
+{
struct RttiInfo;
struct RttiTypeFuncsMap;
struct RttiTypeFuncs
{
- typedef void (*CtorArray)(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count);
- typedef void (*DtorArray)(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count);
- typedef void (*CopyArray)(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, const void* src, Index count);
+ typedef void (
+ *CtorArray)(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count);
+ typedef void (
+ *DtorArray)(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count);
+ typedef void (*CopyArray)(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* dst,
+ const void* src,
+ Index count);
- bool isValid() const { return ctorArray && dtorArray && copyArray; }
+ bool isValid() const { return ctorArray && dtorArray && copyArray; }
- static RttiTypeFuncs makeEmpty() { return RttiTypeFuncs{ nullptr, nullptr, nullptr }; }
+ static RttiTypeFuncs makeEmpty() { return RttiTypeFuncs{nullptr, nullptr, nullptr}; }
CtorArray ctorArray;
DtorArray dtorArray;
@@ -30,11 +37,11 @@ struct RttiTypeFuncs
/* Provides a mechanism to map a type to it's RttiFuncs */
struct RttiTypeFuncsMap
{
- /// For a given type returns the funcs.
- /// If not found returns funcs that return 'isValid' as false.
+ /// For a given type returns the funcs.
+ /// If not found returns funcs that return 'isValid' as false.
RttiTypeFuncs getFuncsForType(const RttiInfo* rttiInfo);
- /// Add funcs for a type
+ /// Add funcs for a type
void add(const RttiInfo* rttiInfo, const RttiTypeFuncs& funcs);
protected:
@@ -42,10 +49,14 @@ protected:
};
/* Template to get funcs for any arbitrary type */
-template <typename T>
+template<typename T>
struct GetRttiTypeFuncs
{
- static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* in, Index count)
+ static void ctorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* in,
+ Index count)
{
SLANG_UNUSED(typeMap);
SLANG_UNUSED(rttiInfo);
@@ -55,7 +66,11 @@ struct GetRttiTypeFuncs
new (dst + i) T;
}
}
- static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* in, Index count)
+ static void dtorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* in,
+ Index count)
{
SLANG_UNUSED(typeMap);
SLANG_UNUSED(rttiInfo);
@@ -65,7 +80,12 @@ struct GetRttiTypeFuncs
(dst + i)->~T();
}
}
- static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
+ static void copyArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ const void* inSrc,
+ Index count)
{
SLANG_UNUSED(rttiInfo);
SLANG_UNUSED(typeMap);
@@ -90,23 +110,36 @@ struct GetRttiTypeFuncs
/* An implementation of funcs, for a type that is POD *and* can be zero initialized.
Built in types generally fall into this catagory, but so do raw pointers and other types,
such as structs that only contain "ZeroPod" types */
-template <typename T>
+template<typename T>
struct GetRttiTypeFuncsForZeroPod
{
- static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count)
+ static void ctorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* dst,
+ Index count)
{
SLANG_UNUSED(typeMap);
SLANG_UNUSED(rttiInfo);
::memset(dst, 0, sizeof(T) * count);
}
- static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, Index count)
+ static void dtorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* dst,
+ Index count)
{
SLANG_UNUSED(typeMap);
SLANG_UNUSED(rttiInfo);
SLANG_UNUSED(dst);
SLANG_UNUSED(count);
}
- static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* dst, const void* src, Index count)
+ static void copyArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* dst,
+ const void* src,
+ Index count)
{
SLANG_UNUSED(typeMap);
SLANG_UNUSED(rttiInfo);
@@ -148,7 +181,7 @@ struct RttiInfo
Enum,
List,
Dictionary,
-
+
CountOf,
};
@@ -156,25 +189,47 @@ struct RttiInfo
AlignmentType m_alignment;
SizeType m_size;
- void init(Kind kind, size_t alignment, size_t size) { m_kind = kind; m_alignment = AlignmentType(alignment); m_size = SizeType(size); }
+ void init(Kind kind, size_t alignment, size_t size)
+ {
+ m_kind = kind;
+ m_alignment = AlignmentType(alignment);
+ m_size = SizeType(size);
+ }
+
+ template<typename T>
+ void init(Kind kind)
+ {
+ init(kind, SLANG_ALIGN_OF(T), sizeof(T));
+ }
- template <typename T>
- void init(Kind kind) { init(kind, SLANG_ALIGN_OF(T), sizeof(T)); }
-
- /// Allocate memory for RttiInfo types.
- /// Is thread safe, and doesn't require the memory to be freed explicitly
- /// Will be freed at shutdown (via global dtor)
+ /// Allocate memory for RttiInfo types.
+ /// Is thread safe, and doesn't require the memory to be freed explicitly
+ /// Will be freed at shutdown (via global dtor)
static void* allocate(size_t size);
- /// Will free up any allocations. Can only be called at shutdown, and there are guarenteed no uses of
- /// RttiInfo - otherwise contents may be undefined.
- /// NOTE! Memory *will* be freed with final dtors, but if memory check functions are used they can report
- /// this memory.
+ /// Will free up any allocations. Can only be called at shutdown, and there are guarenteed no
+ /// uses of RttiInfo - otherwise contents may be undefined. NOTE! Memory *will* be freed with
+ /// final dtors, but if memory check functions are used they can report this memory.
static void deallocateAll();
- static bool isIntegral(RttiInfo::Kind kind) { return Index(kind) >= Index(RttiInfo::Kind::I32) && Index(kind) <= Index(RttiInfo::Kind::U64); }
- static bool isFloat(RttiInfo::Kind kind) { return kind == RttiInfo::Kind::F32 || kind == RttiInfo::Kind::F64; }
- static bool isBuiltIn(RttiInfo::Kind kind) { return Index(kind) >= Index(RttiInfo::Kind::I32) && Index(kind) <= Index(RttiInfo::Kind::Bool); }
- static bool isNamed(RttiInfo::Kind kind) { return Index(kind) >= Index(RttiInfo::Kind::Struct) && Index(kind) <= Index(RttiInfo::Kind::Enum); }
+ static bool isIntegral(RttiInfo::Kind kind)
+ {
+ return Index(kind) >= Index(RttiInfo::Kind::I32) &&
+ Index(kind) <= Index(RttiInfo::Kind::U64);
+ }
+ static bool isFloat(RttiInfo::Kind kind)
+ {
+ return kind == RttiInfo::Kind::F32 || kind == RttiInfo::Kind::F64;
+ }
+ static bool isBuiltIn(RttiInfo::Kind kind)
+ {
+ return Index(kind) >= Index(RttiInfo::Kind::I32) &&
+ Index(kind) <= Index(RttiInfo::Kind::Bool);
+ }
+ static bool isNamed(RttiInfo::Kind kind)
+ {
+ return Index(kind) >= Index(RttiInfo::Kind::Struct) &&
+ Index(kind) <= Index(RttiInfo::Kind::Enum);
+ }
bool isIntegral() const { return isIntegral(m_kind); }
bool isFloat() const { return isFloat(m_kind); }
@@ -190,7 +245,7 @@ struct RttiInfo
// but this works fine for most purposes
enum class RttiDefaultValue : uint8_t
{
- Normal, ///< Zero for integral/float types/false for bool
+ Normal, ///< Zero for integral/float types/false for bool
One,
MinusOne,
@@ -199,7 +254,7 @@ enum class RttiDefaultValue : uint8_t
struct NamedRttiInfo : public RttiInfo
{
- const char* m_name; ///< Name
+ const char* m_name; ///< Name
};
struct StructRttiInfo : public NamedRttiInfo
@@ -216,16 +271,16 @@ struct StructRttiInfo : public NamedRttiInfo
struct Field
{
- const char* m_name; ///< Name of this field
- const RttiInfo* m_type; ///< The type of this field
- uint32_t m_offset; ///< Offset from object type in bytes
- Flags m_flags; ///< Field flags
+ const char* m_name; ///< Name of this field
+ const RttiInfo* m_type; ///< The type of this field
+ uint32_t m_offset; ///< Offset from object type in bytes
+ Flags m_flags; ///< Field flags
};
- const StructRttiInfo* m_super; ///< Super class or nullptr if not defined
+ const StructRttiInfo* m_super; ///< Super class or nullptr if not defined
- Index m_fieldCount; ///< Amount of fields
- const Field* m_fields; ///< Fields
+ Index m_fieldCount; ///< Amount of fields
+ const Field* m_fields; ///< Fields
bool m_ignoreUnknownFieldsInJson = false;
};
@@ -234,7 +289,9 @@ struct EnumRttiInfo : public NamedRttiInfo
// TODO(JS):
};
-SLANG_FORCE_INLINE StructRttiInfo::Flags combine(StructRttiInfo::Flags flags, RttiDefaultValue defaultValue)
+SLANG_FORCE_INLINE StructRttiInfo::Flags combine(
+ StructRttiInfo::Flags flags,
+ RttiDefaultValue defaultValue)
{
return StructRttiInfo::Flags(defaultValue) | flags;
}
@@ -274,23 +331,62 @@ struct OtherRttiInfo : public NamedRttiInfo
};
// The default is to just get the info from a global held inside the type.
-template <typename T>
+template<typename T>
struct GetRttiInfo
{
SLANG_FORCE_INLINE static const RttiInfo* get() { return &T::g_rttiInfo; }
};
-template <> struct GetRttiInfo<bool> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::Bool)];} };
-template <> struct GetRttiInfo<int32_t> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::I32)]; } };
-template <> struct GetRttiInfo<int64_t> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::I64)]; } };
-template <> struct GetRttiInfo<uint32_t> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::U32)]; } };
-template <> struct GetRttiInfo<uint64_t> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::U64)]; } };
-template <> struct GetRttiInfo<float> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::F32)]; } };
-template <> struct GetRttiInfo<double> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::F64)]; } };
-template <> struct GetRttiInfo<String> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::String)]; } };
-template <> struct GetRttiInfo<UnownedStringSlice> { static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::UnownedStringSlice)]; } };
+template<>
+struct GetRttiInfo<bool>
+{
+ static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::Bool)]; }
+};
+template<>
+struct GetRttiInfo<int32_t>
+{
+ static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::I32)]; }
+};
+template<>
+struct GetRttiInfo<int64_t>
+{
+ static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::I64)]; }
+};
+template<>
+struct GetRttiInfo<uint32_t>
+{
+ static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::U32)]; }
+};
+template<>
+struct GetRttiInfo<uint64_t>
+{
+ static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::U64)]; }
+};
+template<>
+struct GetRttiInfo<float>
+{
+ static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::F32)]; }
+};
+template<>
+struct GetRttiInfo<double>
+{
+ static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::F64)]; }
+};
+template<>
+struct GetRttiInfo<String>
+{
+ static const RttiInfo* get() { return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::String)]; }
+};
+template<>
+struct GetRttiInfo<UnownedStringSlice>
+{
+ static const RttiInfo* get()
+ {
+ return &RttiInfo::g_basicTypes[Index(RttiInfo::Kind::UnownedStringSlice)];
+ }
+};
-template <typename T>
+template<typename T>
struct GetRttiInfo<List<T>>
{
static const ListRttiInfo _make()
@@ -300,17 +396,21 @@ struct GetRttiInfo<List<T>>
info.m_elementType = GetRttiInfo<T>::get();
return info;
}
- static const RttiInfo* get() { static const ListRttiInfo g_info = _make(); return &g_info; }
+ static const RttiInfo* get()
+ {
+ static const ListRttiInfo g_info = _make();
+ return &g_info;
+ }
};
// Strip const
-template <typename T>
+template<typename T>
struct GetRttiInfo<const T>
{
static const RttiInfo* get() { return GetRttiInfo<T>::get(); }
};
-template <typename K, typename V>
+template<typename K, typename V>
struct GetRttiInfo<Dictionary<K, V>>
{
static const DictionaryRttiInfo _make()
@@ -321,10 +421,14 @@ struct GetRttiInfo<Dictionary<K, V>>
info.m_valueType = GetRttiInfo<V>::get();
return info;
}
- static const RttiInfo* get() { static const DictionaryRttiInfo g_info = _make(); return &g_info; }
+ static const RttiInfo* get()
+ {
+ static const DictionaryRttiInfo g_info = _make();
+ return &g_info;
+ }
};
-template <typename TARGET>
+template<typename TARGET>
struct GetRttiInfo<TARGET*>
{
static const PtrRttiInfo _make()
@@ -334,10 +438,14 @@ struct GetRttiInfo<TARGET*>
info.m_targetType = GetRttiInfo<TARGET>::get();
return info;
}
- static const RttiInfo* get() { static const PtrRttiInfo g_info = _make(); return &g_info; }
+ static const RttiInfo* get()
+ {
+ static const PtrRttiInfo g_info = _make();
+ return &g_info;
+ }
};
-template <typename TARGET>
+template<typename TARGET>
struct GetRttiInfo<RefPtr<TARGET>>
{
static const RefPtrRttiInfo _make()
@@ -347,10 +455,14 @@ struct GetRttiInfo<RefPtr<TARGET>>
info.m_targetType = GetRttiInfo<TARGET>::get();
return info;
}
- static const RttiInfo* get() { static const RefPtrRttiInfo g_info = _make(); return &g_info; }
+ static const RttiInfo* get()
+ {
+ static const RefPtrRttiInfo g_info = _make();
+ return &g_info;
+ }
};
-template <typename T, size_t COUNT>
+template<typename T, size_t COUNT>
struct GetRttiInfo<T[COUNT]>
{
static const FixedArrayRttiInfo _make()
@@ -363,19 +475,23 @@ struct GetRttiInfo<T[COUNT]>
info.m_elementCount = COUNT;
return info;
}
- static const RttiInfo* get() { static const FixedArrayRttiInfo g_info = _make(); return &g_info; }
+ static const RttiInfo* get()
+ {
+ static const FixedArrayRttiInfo g_info = _make();
+ return &g_info;
+ }
};
struct StructRttiBuilder
{
- template <typename T>
- StructRttiBuilder(T* obj, const char* name, const StructRttiInfo* super)
+ template<typename T>
+ StructRttiBuilder(T* obj, const char* name, const StructRttiInfo* super)
{
m_rttiInfo.init<T>(RttiInfo::Kind::Struct);
_init(name, super, (const Byte*)obj);
}
- template <typename T>
+ template<typename T>
void addField(const char* name, const T* fieldPtr, StructRttiInfo::Flags flags = 0)
{
StructRttiInfo::Field field;
diff --git a/source/core/slang-rtti-util.cpp b/source/core/slang-rtti-util.cpp
index 65ddf8554..701c90e2f 100644
--- a/source/core/slang-rtti-util.cpp
+++ b/source/core/slang-rtti-util.cpp
@@ -1,19 +1,25 @@
#include "slang-rtti-util.h"
-namespace Slang {
+namespace Slang
+{
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RttiTypeFuncs Impls !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RttiTypeFuncs Impls
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
struct ListFuncs
{
- static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void ctorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ Index count)
{
SLANG_UNUSED(typeMap);
SLANG_UNUSED(rttiInfo);
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
// We don't care about the element type, as we can just initialize them all as List<Byte>
- //const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
+ // const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
typedef List<Byte> Type;
Type* dst = (Type*)inDst;
@@ -24,7 +30,12 @@ struct ListFuncs
}
}
- static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
+ static void copyArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ const void* inSrc,
+ Index count)
{
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
@@ -34,7 +45,8 @@ struct ListFuncs
auto typeFuncs = typeMap->getFuncsForType(elementType);
SLANG_ASSERT(typeFuncs.isValid());
- // We need a type that we can get information from the list from - List<Byte> gives us the functions we need.
+ // We need a type that we can get information from the list from - List<Byte> gives us the
+ // functions we need.
typedef List<Byte> Type;
Type* dst = (Type*)inDst;
@@ -71,13 +83,22 @@ struct ListFuncs
}
else
{
- typeFuncs.copyArray(typeMap, elementType, dstList.getBuffer(), srcList.getBuffer(), srcCount);
+ typeFuncs.copyArray(
+ typeMap,
+ elementType,
+ dstList.getBuffer(),
+ srcList.getBuffer(),
+ srcCount);
dstList.unsafeShrinkToCount(srcCount);
}
}
}
- static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void dtorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ Index count)
{
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
@@ -118,14 +139,18 @@ struct ListFuncs
struct StructFuncs
{
- static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void ctorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ Index count)
{
SLANG_UNUSED(typeMap);
SLANG_UNUSED(rttiInfo);
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
// We don't care about the element type, as we can just initialize them all as List<Byte>
- //const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
+ // const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
typedef List<Byte> Type;
Type* dst = (Type*)inDst;
@@ -135,7 +160,12 @@ struct StructFuncs
new (dst + i) Type;
}
}
- static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
+ static void copyArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ const void* inSrc,
+ Index count)
{
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
@@ -145,7 +175,8 @@ struct StructFuncs
auto typeFuncs = typeMap->getFuncsForType(elementType);
SLANG_ASSERT(typeFuncs.isValid());
- // We need a type that we can get information from the list from - List<Byte> gives us the functions we need.
+ // We need a type that we can get information from the list from - List<Byte> gives us the
+ // functions we need.
typedef List<Byte> Type;
Type* dst = (Type*)inDst;
@@ -182,13 +213,22 @@ struct StructFuncs
}
else
{
- typeFuncs.copyArray(typeMap, elementType, dstList.getBuffer(), srcList.getBuffer(), srcCount);
+ typeFuncs.copyArray(
+ typeMap,
+ elementType,
+ dstList.getBuffer(),
+ srcList.getBuffer(),
+ srcCount);
dstList.unsafeShrinkToCount(srcCount);
}
}
}
- static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void dtorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ Index count)
{
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
@@ -229,17 +269,30 @@ struct StructFuncs
struct StructArrayFuncs
{
- static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void ctorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ Index count)
{
return RttiUtil::ctorArray(typeMap, rttiInfo, inDst, rttiInfo->m_size, count);
}
- static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
+ static void copyArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ const void* inSrc,
+ Index count)
{
return RttiUtil::copyArray(typeMap, rttiInfo, inDst, inSrc, rttiInfo->m_size, count);
}
- static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void dtorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ Index count)
{
return RttiUtil::dtorArray(typeMap, rttiInfo, inDst, rttiInfo->m_size, count);
}
@@ -256,33 +309,34 @@ struct StructArrayFuncs
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RttiUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-RttiTypeFuncs RttiUtil::getDefaultTypeFuncs(const RttiInfo* rttiInfo)
+RttiTypeFuncs RttiUtil::getDefaultTypeFuncs(const RttiInfo* rttiInfo)
{
if (rttiInfo->isBuiltIn())
{
switch (rttiInfo->m_size)
{
- case 1: return GetRttiTypeFuncsForZeroPod<uint8_t>::getFuncs();
- case 2: return GetRttiTypeFuncsForZeroPod<uint16_t>::getFuncs();
- case 4: return GetRttiTypeFuncsForZeroPod<uint32_t>::getFuncs();
- case 8: return GetRttiTypeFuncsForZeroPod<uint64_t>::getFuncs();
+ case 1: return GetRttiTypeFuncsForZeroPod<uint8_t>::getFuncs();
+ case 2: return GetRttiTypeFuncsForZeroPod<uint16_t>::getFuncs();
+ case 4: return GetRttiTypeFuncsForZeroPod<uint32_t>::getFuncs();
+ case 8: return GetRttiTypeFuncsForZeroPod<uint64_t>::getFuncs();
}
return RttiTypeFuncs::makeEmpty();
}
switch (rttiInfo->m_kind)
{
- case RttiInfo::Kind::String: return GetRttiTypeFuncs<String>::getFuncs();
- case RttiInfo::Kind::UnownedStringSlice: return GetRttiTypeFuncs<UnownedStringSlice>::getFuncs();
- case RttiInfo::Kind::List: return ListFuncs::getFuncs();
- case RttiInfo::Kind::Struct: return StructArrayFuncs::getFuncs();
- default: break;
+ case RttiInfo::Kind::String: return GetRttiTypeFuncs<String>::getFuncs();
+ case RttiInfo::Kind::UnownedStringSlice:
+ return GetRttiTypeFuncs<UnownedStringSlice>::getFuncs();
+ case RttiInfo::Kind::List: return ListFuncs::getFuncs();
+ case RttiInfo::Kind::Struct: return StructArrayFuncs::getFuncs();
+ default: break;
}
return RttiTypeFuncs::makeEmpty();
}
-/* static */SlangResult RttiUtil::setInt(int64_t value, const RttiInfo* rttiInfo, void* dst)
+/* static */ SlangResult RttiUtil::setInt(int64_t value, const RttiInfo* rttiInfo, void* dst)
{
SLANG_ASSERT(rttiInfo->isIntegral());
@@ -290,33 +344,33 @@ RttiTypeFuncs RttiUtil::getDefaultTypeFuncs(const RttiInfo* rttiInfo)
// Passing in rttiInfo allows for other more complex types to be econverted
switch (rttiInfo->m_kind)
{
- case RttiInfo::Kind::I32: *(int32_t*)dst = int32_t(value); break;
- case RttiInfo::Kind::U32: *(uint32_t*)dst = uint32_t(value); break;
- case RttiInfo::Kind::I64: *(int64_t*)dst = int64_t(value); break;
- case RttiInfo::Kind::U64: *(uint64_t*)dst = uint64_t(value); break;
- default: return SLANG_FAIL;
+ case RttiInfo::Kind::I32: *(int32_t*)dst = int32_t(value); break;
+ case RttiInfo::Kind::U32: *(uint32_t*)dst = uint32_t(value); break;
+ case RttiInfo::Kind::I64: *(int64_t*)dst = int64_t(value); break;
+ case RttiInfo::Kind::U64: *(uint64_t*)dst = uint64_t(value); break;
+ default: return SLANG_FAIL;
}
return SLANG_OK;
}
-/* static */int64_t RttiUtil::getInt64(const RttiInfo* rttiInfo, const void* src)
+/* static */ int64_t RttiUtil::getInt64(const RttiInfo* rttiInfo, const void* src)
{
SLANG_ASSERT(rttiInfo->isIntegral());
switch (rttiInfo->m_kind)
{
- case RttiInfo::Kind::I32: return *(const int32_t*)src;
- case RttiInfo::Kind::U32: return *(const uint32_t*)src;
- case RttiInfo::Kind::I64: return *(const int64_t*)src;
- case RttiInfo::Kind::U64: return *(const uint64_t*)src;
- default: break;
+ case RttiInfo::Kind::I32: return *(const int32_t*)src;
+ case RttiInfo::Kind::U32: return *(const uint32_t*)src;
+ case RttiInfo::Kind::I64: return *(const int64_t*)src;
+ case RttiInfo::Kind::U64: return *(const uint64_t*)src;
+ default: break;
}
SLANG_ASSERT(!"Not integral!");
return -1;
}
-/* static */double RttiUtil::asDouble(const RttiInfo* rttiInfo, const void* src)
+/* static */ double RttiUtil::asDouble(const RttiInfo* rttiInfo, const void* src)
{
if (rttiInfo->isIntegral())
{
@@ -326,9 +380,9 @@ RttiTypeFuncs RttiUtil::getDefaultTypeFuncs(const RttiInfo* rttiInfo)
{
switch (rttiInfo->m_kind)
{
- case RttiInfo::Kind::F32: return *(const float*)src;
- case RttiInfo::Kind::F64: return *(const double*)src;
- default: break;
+ case RttiInfo::Kind::F32: return *(const float*)src;
+ case RttiInfo::Kind::F64: return *(const double*)src;
+ default: break;
}
}
@@ -336,7 +390,7 @@ RttiTypeFuncs RttiUtil::getDefaultTypeFuncs(const RttiInfo* rttiInfo)
return 0.0;
}
-/* static */SlangResult RttiUtil::setFromDouble(double v, const RttiInfo* rttiInfo, void* dst)
+/* static */ SlangResult RttiUtil::setFromDouble(double v, const RttiInfo* rttiInfo, void* dst)
{
if (rttiInfo->isIntegral())
{
@@ -346,16 +400,16 @@ RttiTypeFuncs RttiUtil::getDefaultTypeFuncs(const RttiInfo* rttiInfo)
{
switch (rttiInfo->m_kind)
{
- case RttiInfo::Kind::F32: *(float*)dst = float(v); return SLANG_OK;
- case RttiInfo::Kind::F64: *(double*)dst = v; return SLANG_OK;
- default: break;
+ case RttiInfo::Kind::F32: *(float*)dst = float(v); return SLANG_OK;
+ case RttiInfo::Kind::F64: *(double*)dst = v; return SLANG_OK;
+ default: break;
}
}
return SLANG_FAIL;
}
-/* static */bool RttiUtil::asBool(const RttiInfo* rttiInfo, const void* src)
+/* static */ bool RttiUtil::asBool(const RttiInfo* rttiInfo, const void* src)
{
if (rttiInfo->m_kind == RttiInfo::Kind::Bool)
{
@@ -379,10 +433,10 @@ static int64_t _getIntDefaultValue(RttiDefaultValue value)
{
switch (value)
{
- default:
- case RttiDefaultValue::Normal: return 0;
- case RttiDefaultValue::One: return 1;
- case RttiDefaultValue::MinusOne: return -1;
+ default:
+ case RttiDefaultValue::Normal: return 0;
+ case RttiDefaultValue::One: return 1;
+ case RttiDefaultValue::MinusOne: return -1;
}
}
@@ -403,7 +457,8 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
{
const auto& field = type->m_fields[i];
- const RttiDefaultValue defaultValue = RttiDefaultValue(field.m_flags & uint8_t(RttiDefaultValue::Mask));
+ const RttiDefaultValue defaultValue =
+ RttiDefaultValue(field.m_flags & uint8_t(RttiDefaultValue::Mask));
if (!RttiUtil::isDefault(defaultValue, field.m_type, base + field.m_offset))
{
@@ -414,7 +469,10 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
return true;
}
-/* static */bool RttiUtil::isDefault(RttiDefaultValue defaultValue, const RttiInfo* rttiInfo, const void* src)
+/* static */ bool RttiUtil::isDefault(
+ RttiDefaultValue defaultValue,
+ const RttiInfo* rttiInfo,
+ const void* src)
{
if (rttiInfo->isIntegral())
{
@@ -429,52 +487,56 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
switch (rttiInfo->m_kind)
{
- case RttiInfo::Kind::Invalid: return true;
- case RttiInfo::Kind::Bool: return *(const bool*)src == (_getIntDefaultValue(defaultValue) != 0);
- case RttiInfo::Kind::String:
+ case RttiInfo::Kind::Invalid: return true;
+ case RttiInfo::Kind::Bool: return *(const bool*)src == (_getIntDefaultValue(defaultValue) != 0);
+ case RttiInfo::Kind::String:
{
return ((const String*)src)->getLength() == 0;
}
- case RttiInfo::Kind::UnownedStringSlice:
+ case RttiInfo::Kind::UnownedStringSlice:
{
return ((const UnownedStringSlice*)src)->getLength() == 0;
}
- case RttiInfo::Kind::Struct:
+ case RttiInfo::Kind::Struct:
{
return _isStructDefault(static_cast<const StructRttiInfo*>(rttiInfo), src);
}
- case RttiInfo::Kind::Enum:
+ case RttiInfo::Kind::Enum:
{
SLANG_ASSERT(!"Not implemented yet");
return false;
}
- case RttiInfo::Kind::List:
+ case RttiInfo::Kind::List:
{
const auto& v = *(const List<Byte>*)src;
return v.getCount() == 0;
}
- case RttiInfo::Kind::Dictionary:
+ case RttiInfo::Kind::Dictionary:
{
const auto& v = *(const Dictionary<Byte, Byte>*)src;
return v.getCount() == 0;
}
- case RttiInfo::Kind::Other:
+ case RttiInfo::Kind::Other:
{
const OtherRttiInfo* otherRttiInfo = static_cast<const OtherRttiInfo*>(rttiInfo);
return otherRttiInfo->m_isDefaultFunc && otherRttiInfo->m_isDefaultFunc(rttiInfo, src);
}
- default:
+ default:
{
return false;
}
}
}
-/* static */SlangResult RttiUtil::setListCount(RttiTypeFuncsMap* typeMap, const RttiInfo* elementType, void* dst, Index count)
+/* static */ SlangResult RttiUtil::setListCount(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* elementType,
+ void* dst,
+ Index count)
{
// NOTE! The following only works because List<T> has capacity initialized members, and
// setting the count if it is <= capacity just sets the count (ie things aren't released(!)).
-
+
List<Byte>& dstList = *(List<Byte>*)dst;
const Index oldCount = dstList.getCount();
if (oldCount == count)
@@ -512,34 +574,35 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
return SLANG_OK;
}
-/* static */bool RttiUtil::canMemCpy(const RttiInfo* type)
+/* static */ bool RttiUtil::canMemCpy(const RttiInfo* type)
{
switch (type->m_kind)
{
- case RttiInfo::Kind::RefPtr:
- case RttiInfo::Kind::String:
- case RttiInfo::Kind::Invalid:
+ case RttiInfo::Kind::RefPtr:
+ case RttiInfo::Kind::String:
+ case RttiInfo::Kind::Invalid:
{
return false;
}
- case RttiInfo::Kind::UnownedStringSlice:
- case RttiInfo::Kind::Ptr:
- case RttiInfo::Kind::Enum:
+ case RttiInfo::Kind::UnownedStringSlice:
+ case RttiInfo::Kind::Ptr:
+ case RttiInfo::Kind::Enum:
{
return true;
}
- case RttiInfo::Kind::FixedArray:
+ case RttiInfo::Kind::FixedArray:
{
- const FixedArrayRttiInfo* fixedArrayRttiInfo = static_cast<const FixedArrayRttiInfo*>(type);
+ const FixedArrayRttiInfo* fixedArrayRttiInfo =
+ static_cast<const FixedArrayRttiInfo*>(type);
return canMemCpy(fixedArrayRttiInfo->m_elementType);
}
- case RttiInfo::Kind::Other:
- case RttiInfo::Kind::List:
- case RttiInfo::Kind::Dictionary:
+ case RttiInfo::Kind::Other:
+ case RttiInfo::Kind::List:
+ case RttiInfo::Kind::Dictionary:
{
return false;
}
- case RttiInfo::Kind::Struct:
+ case RttiInfo::Kind::Struct:
{
const StructRttiInfo* structRttiInfo = static_cast<const StructRttiInfo*>(type);
@@ -558,51 +621,51 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
}
}
structRttiInfo = structRttiInfo->m_super;
- }
- while (structRttiInfo);
+ } while (structRttiInfo);
return true;
}
- default:
+ default:
{
return type->isBuiltIn();
}
}
}
-/* static */bool RttiUtil::canZeroInit(const RttiInfo* type)
+/* static */ bool RttiUtil::canZeroInit(const RttiInfo* type)
{
switch (type->m_kind)
{
- case RttiInfo::Kind::Invalid:
+ case RttiInfo::Kind::Invalid:
{
return true;
}
- case RttiInfo::Kind::String:
+ case RttiInfo::Kind::String:
{
// As it stands we can zero init String, but if impl changes that might not
// be true
return true;
}
- case RttiInfo::Kind::UnownedStringSlice:
- case RttiInfo::Kind::Ptr:
- case RttiInfo::Kind::RefPtr:
- case RttiInfo::Kind::Enum:
+ case RttiInfo::Kind::UnownedStringSlice:
+ case RttiInfo::Kind::Ptr:
+ case RttiInfo::Kind::RefPtr:
+ case RttiInfo::Kind::Enum:
{
return true;
}
- case RttiInfo::Kind::FixedArray:
+ case RttiInfo::Kind::FixedArray:
{
- const FixedArrayRttiInfo* fixedArrayRttiInfo = static_cast<const FixedArrayRttiInfo*>(type);
+ const FixedArrayRttiInfo* fixedArrayRttiInfo =
+ static_cast<const FixedArrayRttiInfo*>(type);
return canZeroInit(fixedArrayRttiInfo->m_elementType);
}
- case RttiInfo::Kind::Other:
- case RttiInfo::Kind::List:
- case RttiInfo::Kind::Dictionary:
+ case RttiInfo::Kind::Other:
+ case RttiInfo::Kind::List:
+ case RttiInfo::Kind::Dictionary:
{
return false;
}
- case RttiInfo::Kind::Struct:
+ case RttiInfo::Kind::Struct:
{
const StructRttiInfo* structRttiInfo = static_cast<const StructRttiInfo*>(type);
@@ -621,49 +684,49 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
}
}
structRttiInfo = structRttiInfo->m_super;
- }
- while (structRttiInfo);
+ } while (structRttiInfo);
return true;
}
- default:
+ default:
{
return type->isBuiltIn();
}
}
}
-/* static */bool RttiUtil::hasDtor(const RttiInfo* type)
+/* static */ bool RttiUtil::hasDtor(const RttiInfo* type)
{
switch (type->m_kind)
{
- case RttiInfo::Kind::Invalid:
+ case RttiInfo::Kind::Invalid:
{
return false;
}
- case RttiInfo::Kind::String:
- case RttiInfo::Kind::RefPtr:
+ case RttiInfo::Kind::String:
+ case RttiInfo::Kind::RefPtr:
{
return true;
}
- case RttiInfo::Kind::UnownedStringSlice:
- case RttiInfo::Kind::Ptr:
- case RttiInfo::Kind::Enum:
+ case RttiInfo::Kind::UnownedStringSlice:
+ case RttiInfo::Kind::Ptr:
+ case RttiInfo::Kind::Enum:
{
return false;
}
- case RttiInfo::Kind::FixedArray:
+ case RttiInfo::Kind::FixedArray:
{
- const FixedArrayRttiInfo* fixedArrayRttiInfo = static_cast<const FixedArrayRttiInfo*>(type);
+ const FixedArrayRttiInfo* fixedArrayRttiInfo =
+ static_cast<const FixedArrayRttiInfo*>(type);
return hasDtor(fixedArrayRttiInfo->m_elementType);
}
- case RttiInfo::Kind::Other:
- case RttiInfo::Kind::List:
- case RttiInfo::Kind::Dictionary:
+ case RttiInfo::Kind::Other:
+ case RttiInfo::Kind::List:
+ case RttiInfo::Kind::Dictionary:
{
return true;
}
- case RttiInfo::Kind::Struct:
+ case RttiInfo::Kind::Struct:
{
const StructRttiInfo* structRttiInfo = static_cast<const StructRttiInfo*>(type);
@@ -682,18 +745,22 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
}
}
structRttiInfo = structRttiInfo->m_super;
- }
- while (structRttiInfo);
+ } while (structRttiInfo);
return false;
}
- default:
+ default:
{
return !type->isBuiltIn();
}
}
}
-/* static */void RttiUtil::ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, ptrdiff_t stride, Index count)
+/* static */ void RttiUtil::ctorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ ptrdiff_t stride,
+ Index count)
{
if (count <= 0)
{
@@ -720,28 +787,39 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
switch (rttiInfo->m_kind)
{
- case RttiInfo::Kind::FixedArray:
+ case RttiInfo::Kind::FixedArray:
{
- const FixedArrayRttiInfo* fixedArrayRttiInfo = static_cast<const FixedArrayRttiInfo*>(rttiInfo);
+ const FixedArrayRttiInfo* fixedArrayRttiInfo =
+ static_cast<const FixedArrayRttiInfo*>(rttiInfo);
if (fixedArrayRttiInfo->m_size == stride)
{
// It's contiguous do in one go
- ctorArray(typeMap, fixedArrayRttiInfo->m_elementType, dst, fixedArrayRttiInfo->m_elementType->m_size, fixedArrayRttiInfo->m_elementCount * count);
+ ctorArray(
+ typeMap,
+ fixedArrayRttiInfo->m_elementType,
+ dst,
+ fixedArrayRttiInfo->m_elementType->m_size,
+ fixedArrayRttiInfo->m_elementCount * count);
}
else
{
// Do it in array runs
for (Index i = 0; i < count; ++i, dst += stride)
{
- ctorArray(typeMap, fixedArrayRttiInfo->m_elementType, dst, fixedArrayRttiInfo->m_elementType->m_size, fixedArrayRttiInfo->m_elementCount);
+ ctorArray(
+ typeMap,
+ fixedArrayRttiInfo->m_elementType,
+ dst,
+ fixedArrayRttiInfo->m_elementType->m_size,
+ fixedArrayRttiInfo->m_elementCount);
}
}
return;
}
- case RttiInfo::Kind::List:
- case RttiInfo::Kind::Dictionary:
- case RttiInfo::Kind::Other:
+ case RttiInfo::Kind::List:
+ case RttiInfo::Kind::Dictionary:
+ case RttiInfo::Kind::Other:
{
auto funcs = typeMap->getFuncsForType(rttiInfo);
SLANG_ASSERT(funcs.isValid());
@@ -761,7 +839,7 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
}
return;
}
- case RttiInfo::Kind::Struct:
+ case RttiInfo::Kind::Struct:
{
const StructRttiInfo* structRttiInfo = static_cast<const StructRttiInfo*>(rttiInfo);
@@ -777,17 +855,22 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
ctorArray(typeMap, field.m_type, dst + field.m_offset, stride, count);
}
structRttiInfo = structRttiInfo->m_super;
- }
- while(structRttiInfo);
+ } while (structRttiInfo);
return;
}
}
-
+
SLANG_ASSERT(!"Unexpected");
}
-/* static */void RttiUtil::copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, ptrdiff_t stride, Index count)
+/* static */ void RttiUtil::copyArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ const void* inSrc,
+ ptrdiff_t stride,
+ Index count)
{
if (count <= 0)
{
@@ -806,7 +889,7 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
}
else
{
-
+
for (Index i = 0; i < count; ++i, dst += stride, src += stride)
{
::memcpy(dst, src, size);
@@ -817,9 +900,10 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
switch (rttiInfo->m_kind)
{
- case RttiInfo::Kind::FixedArray:
+ case RttiInfo::Kind::FixedArray:
{
- const FixedArrayRttiInfo* fixedArrayRttiInfo = static_cast<const FixedArrayRttiInfo*>(rttiInfo);
+ const FixedArrayRttiInfo* fixedArrayRttiInfo =
+ static_cast<const FixedArrayRttiInfo*>(rttiInfo);
const auto elementType = fixedArrayRttiInfo->m_elementType;
const auto elementSize = elementType->m_size;
const auto elementCount = fixedArrayRttiInfo->m_elementCount;
@@ -839,9 +923,9 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
}
return;
}
- case RttiInfo::Kind::List:
- case RttiInfo::Kind::Dictionary:
- case RttiInfo::Kind::Other:
+ case RttiInfo::Kind::List:
+ case RttiInfo::Kind::Dictionary:
+ case RttiInfo::Kind::Other:
{
auto funcs = typeMap->getFuncsForType(rttiInfo);
SLANG_ASSERT(funcs.isValid());
@@ -860,7 +944,7 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
}
return;
}
- case RttiInfo::Kind::Struct:
+ case RttiInfo::Kind::Struct:
{
const StructRttiInfo* structRttiInfo = static_cast<const StructRttiInfo*>(rttiInfo);
@@ -873,11 +957,16 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
for (Index i = 0; i < fieldCount; ++i)
{
const auto& field = fields[i];
- copyArray(typeMap, field.m_type, dst + field.m_offset, src + field.m_offset, stride, count);
+ copyArray(
+ typeMap,
+ field.m_type,
+ dst + field.m_offset,
+ src + field.m_offset,
+ stride,
+ count);
}
structRttiInfo = structRttiInfo->m_super;
- }
- while (structRttiInfo);
+ } while (structRttiInfo);
return;
}
@@ -886,7 +975,12 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
SLANG_ASSERT(!"Unexpected");
}
-/* static */void RttiUtil::dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, ptrdiff_t stride, Index count)
+/* static */ void RttiUtil::dtorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ ptrdiff_t stride,
+ Index count)
{
if (count <= 0 || !hasDtor(rttiInfo))
{
@@ -898,9 +992,10 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
switch (rttiInfo->m_kind)
{
- case RttiInfo::Kind::FixedArray:
+ case RttiInfo::Kind::FixedArray:
{
- const FixedArrayRttiInfo* fixedArrayRttiInfo = static_cast<const FixedArrayRttiInfo*>(rttiInfo);
+ const FixedArrayRttiInfo* fixedArrayRttiInfo =
+ static_cast<const FixedArrayRttiInfo*>(rttiInfo);
const auto elementType = fixedArrayRttiInfo->m_elementType;
const auto elementSize = elementType->m_size;
const auto elementCount = fixedArrayRttiInfo->m_elementCount;
@@ -920,9 +1015,9 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
}
return;
}
- case RttiInfo::Kind::List:
- case RttiInfo::Kind::Dictionary:
- case RttiInfo::Kind::Other:
+ case RttiInfo::Kind::List:
+ case RttiInfo::Kind::Dictionary:
+ case RttiInfo::Kind::Other:
{
auto funcs = typeMap->getFuncsForType(rttiInfo);
SLANG_ASSERT(funcs.isValid());
@@ -941,7 +1036,7 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
}
return;
}
- case RttiInfo::Kind::Struct:
+ case RttiInfo::Kind::Struct:
{
const StructRttiInfo* structRttiInfo = static_cast<const StructRttiInfo*>(rttiInfo);
@@ -957,8 +1052,7 @@ static bool _isStructDefault(const StructRttiInfo* type, const void* src)
dtorArray(typeMap, field.m_type, dst + field.m_offset, stride, count);
}
structRttiInfo = structRttiInfo->m_super;
- }
- while (structRttiInfo);
+ } while (structRttiInfo);
return;
}
diff --git a/source/core/slang-rtti-util.h b/source/core/slang-rtti-util.h
index 4807c5ea2..0058eaddf 100644
--- a/source/core/slang-rtti-util.h
+++ b/source/core/slang-rtti-util.h
@@ -25,31 +25,33 @@
//
// Convert from such JSON objects using JSONToNativeConverter::convert
-#define SLANG_MAKE_STRUCT_RTTI_INFO(S, ...) \
- template<> \
- struct GetRttiInfo<S> \
- { \
- static const RttiInfo* get() \
- { \
- using S_ = S; \
- const static StructRttiInfo::Field fs[] = {__VA_ARGS__}; \
- const auto ignoreUnknownFields = true; \
- const static auto ret = StructRttiInfo{ \
+#define SLANG_MAKE_STRUCT_RTTI_INFO(S, ...) \
+ template<> \
+ struct GetRttiInfo<S> \
+ { \
+ static const RttiInfo* get() \
+ { \
+ using S_ = S; \
+ const static StructRttiInfo::Field fs[] = {__VA_ARGS__}; \
+ const auto ignoreUnknownFields = true; \
+ const static auto ret = StructRttiInfo{ \
{{RttiInfo::Kind::Struct, alignof(S), sizeof(S)}, #S}, \
- nullptr, \
- SLANG_COUNT_OF(fs), \
- fs, \
- ignoreUnknownFields \
- }; \
- return &ret; \
- } \
+ nullptr, \
+ SLANG_COUNT_OF(fs), \
+ fs, \
+ ignoreUnknownFields}; \
+ return &ret; \
+ } \
};
-#define SLANG_RTTI_FIELD_IMPL(m, name, flags) \
- {name, GetRttiInfo<decltype(S_::m)>::get(), offsetof(S_, m), flags}
+#define SLANG_RTTI_FIELD_IMPL(m, name, flags) \
+ { \
+ name, GetRttiInfo<decltype(S_::m)>::get(), offsetof(S_, m), flags \
+ }
#define SLANG_RTTI_FIELD(m) SLANG_RTTI_FIELD_IMPL(m, #m, 0)
#define SLANG_OPTIONAL_RTTI_FIELD(m) SLANG_RTTI_FIELD_IMPL(m, #m, StructRttiInfo::Flag::Optional)
-namespace Slang {
+namespace Slang
+{
struct RttiUtil
{
@@ -64,22 +66,42 @@ struct RttiUtil
static bool isDefault(RttiDefaultValue defaultValue, const RttiInfo* rttiInfo, const void* src);
- /// Gets funcs for default scenarios
+ /// Gets funcs for default scenarios
static RttiTypeFuncs getDefaultTypeFuncs(const RttiInfo* rttiInfo);
- /// Set a list count
- static SlangResult setListCount(RttiTypeFuncsMap* typeMap, const RttiInfo* elementType, void* dst, Index count);
+ /// Set a list count
+ static SlangResult setListCount(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* elementType,
+ void* dst,
+ Index count);
- /// Returns if the type can be zero initialized
+ /// Returns if the type can be zero initialized
static bool canZeroInit(const RttiInfo* type);
- /// Returns true if the type needs dtor
+ /// Returns true if the type needs dtor
static bool hasDtor(const RttiInfo* type);
- /// Returns true if we can memcpy to copy
+ /// Returns true if we can memcpy to copy
static bool canMemCpy(const RttiInfo* type);
- static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, ptrdiff_t stride, Index count);
- static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, ptrdiff_t stride, Index count);
- static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, ptrdiff_t stride, Index count);
+ static void ctorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ ptrdiff_t stride,
+ Index count);
+ static void copyArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ const void* inSrc,
+ ptrdiff_t stride,
+ Index count);
+ static void dtorArray(
+ RttiTypeFuncsMap* typeMap,
+ const RttiInfo* rttiInfo,
+ void* inDst,
+ ptrdiff_t stride,
+ Index count);
};
} // namespace Slang
diff --git a/source/core/slang-secure-crt.h b/source/core/slang-secure-crt.h
index 46552914a..57e38f0dd 100644
--- a/source/core/slang-secure-crt.h
+++ b/source/core/slang-secure-crt.h
@@ -1,16 +1,15 @@
#ifndef _MSC_VER
#ifndef SLANG_CORE_SECURE_CRT_H
#define SLANG_CORE_SECURE_CRT_H
+#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
-#include <assert.h>
-
#include <wchar.h>
-inline void memcpy_s(void *dest, [[maybe_unused]] size_t destSize, const void * src, size_t count)
+inline void memcpy_s(void* dest, [[maybe_unused]] size_t destSize, const void* src, size_t count)
{
assert(destSize >= count);
memcpy(dest, src, count);
@@ -19,75 +18,92 @@ inline void memcpy_s(void *dest, [[maybe_unused]] size_t destSize, const void *
#define _TRUNCATE ((size_t)-1)
#define _stricmp strcasecmp
-inline void fopen_s(FILE**f, const char * fileName, const char * mode)
+inline void fopen_s(FILE** f, const char* fileName, const char* mode)
{
- *f = fopen(fileName, mode);
+ *f = fopen(fileName, mode);
}
-inline size_t fread_s(void * buffer, [[maybe_unused]] size_t bufferSize, size_t elementSize, size_t count, FILE * stream)
+inline size_t fread_s(
+ void* buffer,
+ [[maybe_unused]] size_t bufferSize,
+ size_t elementSize,
+ size_t count,
+ FILE* stream)
{
assert(bufferSize >= elementSize * count);
return fread(buffer, elementSize, count, stream);
}
-inline size_t wcsnlen_s(const wchar_t * str, size_t /*numberofElements*/)
+inline size_t wcsnlen_s(const wchar_t* str, size_t /*numberofElements*/)
{
- return wcslen(str);
+ return wcslen(str);
}
-inline size_t strnlen_s(const char * str, size_t numberOfElements)
+inline size_t strnlen_s(const char* str, size_t numberOfElements)
{
-#if defined( __CYGWIN__ )
+#if defined(__CYGWIN__)
const char* cur = str;
if (str)
{
- const char*const end = str + numberOfElements;
- while (*cur && cur < end) cur++;
+ const char* const end = str + numberOfElements;
+ while (*cur && cur < end)
+ cur++;
}
return size_t(cur - str);
#else
- return strnlen(str, numberOfElements);
+ return strnlen(str, numberOfElements);
#endif
}
-__attribute__((format(printf, 3, 4)))
-inline int sprintf_s(char * buffer, size_t sizeOfBuffer, const char * format, ...)
+__attribute__((format(printf, 3, 4))) inline int sprintf_s(
+ char* buffer,
+ size_t sizeOfBuffer,
+ const char* format,
+ ...)
{
- va_list argptr;
- va_start(argptr, format);
- int rs = vsnprintf(buffer, sizeOfBuffer, format, argptr);
- va_end(argptr);
- return rs;
+ va_list argptr;
+ va_start(argptr, format);
+ int rs = vsnprintf(buffer, sizeOfBuffer, format, argptr);
+ va_end(argptr);
+ return rs;
}
// A patch was submitted to GCC wchar_t support in 2001, so I'm sure we can
// enable this any day now...
// __attribute__((format(wprintf, 3, 4)))
-inline int swprintf_s(wchar_t * buffer, size_t sizeOfBuffer, const wchar_t * format, ...)
+inline int swprintf_s(wchar_t* buffer, size_t sizeOfBuffer, const wchar_t* format, ...)
{
- va_list argptr;
- va_start(argptr, format);
- int rs = vswprintf(buffer, sizeOfBuffer, format, argptr);
- va_end(argptr);
- return rs;
+ va_list argptr;
+ va_start(argptr, format);
+ int rs = vswprintf(buffer, sizeOfBuffer, format, argptr);
+ va_end(argptr);
+ return rs;
}
-inline void wcscpy_s(wchar_t * strDestination, size_t /*numberOfElements*/, const wchar_t * strSource)
+inline void wcscpy_s(wchar_t* strDestination, size_t /*numberOfElements*/, const wchar_t* strSource)
{
- wcscpy(strDestination, strSource);
+ wcscpy(strDestination, strSource);
}
-inline void strcpy_s(char * strDestination, size_t /*numberOfElements*/, const char * strSource)
+inline void strcpy_s(char* strDestination, size_t /*numberOfElements*/, const char* strSource)
{
- strcpy(strDestination, strSource);
+ strcpy(strDestination, strSource);
}
-inline void wcsncpy_s(wchar_t * strDestination, size_t /*numberOfElements*/, const wchar_t * strSource, size_t count)
+inline void wcsncpy_s(
+ wchar_t* strDestination,
+ size_t /*numberOfElements*/,
+ const wchar_t* strSource,
+ size_t count)
{
- wcsncpy(strDestination, strSource, count);
+ wcsncpy(strDestination, strSource, count);
}
-inline void strncpy_s(char * strDestination, size_t /*numberOfElements*/, const char * strSource, size_t count)
+inline void strncpy_s(
+ char* strDestination,
+ size_t /*numberOfElements*/,
+ const char* strSource,
+ size_t count)
{
- strncpy(strDestination, strSource, count);
+ strncpy(strDestination, strSource, count);
}
#endif
#endif
diff --git a/source/core/slang-semantic-version.cpp b/source/core/slang-semantic-version.cpp
index 9e68de746..ab7b5007b 100644
--- a/source/core/slang-semantic-version.cpp
+++ b/source/core/slang-semantic-version.cpp
@@ -1,15 +1,18 @@
// slang-semantic-version.cpp
#include "slang-semantic-version.h"
-#include "slang-com-helper.h"
-
#include "../core/slang-string-util.h"
+#include "slang-com-helper.h"
-namespace Slang {
+namespace Slang
+{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SemanticVersion !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-SlangResult SemanticVersion::parse(const UnownedStringSlice& value, char separatorChar, SemanticVersion& outVersion)
+SlangResult SemanticVersion::parse(
+ const UnownedStringSlice& value,
+ char separatorChar,
+ SemanticVersion& outVersion)
{
outVersion.reset();
@@ -21,7 +24,7 @@ SlangResult SemanticVersion::parse(const UnownedStringSlice& value, char separat
return SLANG_FAIL;
}
- Int ints[3] = { 0, 0, 0 };
+ Int ints[3] = {0, 0, 0};
for (Index i = 0; i < splitCount; i++)
{
SLANG_RETURN_ON_FAIL(StringUtil::parseInt(slices[i], ints[i]));
@@ -40,7 +43,7 @@ SlangResult SemanticVersion::parse(const UnownedStringSlice& value, char separat
return SLANG_OK;
}
-SlangResult SemanticVersion::parse(const UnownedStringSlice& value, SemanticVersion& outVersion)
+SlangResult SemanticVersion::parse(const UnownedStringSlice& value, SemanticVersion& outVersion)
{
return parse(value, '.', outVersion);
}
@@ -54,7 +57,7 @@ void SemanticVersion::append(StringBuilder& buf) const
}
}
-/* static */SemanticVersion SemanticVersion::getEarliest(const ThisType* versions, Count count)
+/* static */ SemanticVersion SemanticVersion::getEarliest(const ThisType* versions, Count count)
{
if (count <= 0)
{
@@ -72,7 +75,7 @@ void SemanticVersion::append(StringBuilder& buf) const
return bestVersion;
}
-/* static */SemanticVersion SemanticVersion::getLatest(const ThisType* versions, Count count)
+/* static */ SemanticVersion SemanticVersion::getLatest(const ThisType* versions, Count count)
{
if (count <= 0)
{
@@ -92,7 +95,10 @@ void SemanticVersion::append(StringBuilder& buf) const
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MatchSemanticVersion !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-/* static */SemanticVersion MatchSemanticVersion::findAnyBest(const SemanticVersion* versions, Count count, const ThisType& matchVersion)
+/* static */ SemanticVersion MatchSemanticVersion::findAnyBest(
+ const SemanticVersion* versions,
+ Count count,
+ const ThisType& matchVersion)
{
// If there aren't any we are done
if (count <= 0)
@@ -111,48 +117,58 @@ void SemanticVersion::append(StringBuilder& buf) const
switch (matchVersion.m_kind)
{
- case Kind::Past:
+ case Kind::Past:
{
return SemanticVersion::getEarliest(versions, count);
}
- case Kind::Unknown:
- case Kind::Future:
+ case Kind::Unknown:
+ case Kind::Future:
{
// If it's unknown, we just get the latest
return SemanticVersion::getLatest(versions, count);
}
- case Kind::Major:
+ case Kind::Major:
{
start = SemanticVersion(matchVersion.m_version.m_major, 0, 0);
end = SemanticVersion(matchVersion.m_version.m_major + 1, 0, 0);
break;
}
- case Kind::MajorMinor:
+ case Kind::MajorMinor:
{
- start = SemanticVersion(matchVersion.m_version.m_major, matchVersion.m_version.m_minor, 0);
- end = SemanticVersion(matchVersion.m_version.m_major, matchVersion.m_version.m_minor + 1, 0);
+ start =
+ SemanticVersion(matchVersion.m_version.m_major, matchVersion.m_version.m_minor, 0);
+ end = SemanticVersion(
+ matchVersion.m_version.m_major,
+ matchVersion.m_version.m_minor + 1,
+ 0);
break;
}
- case Kind::MajorMinorPatch:
+ case Kind::MajorMinorPatch:
{
start = SemanticVersion(matchVersion.m_version);
- end = SemanticVersion(matchVersion.m_version.m_major, matchVersion.m_version.m_minor, matchVersion.m_version.m_patch + 1);
+ end = SemanticVersion(
+ matchVersion.m_version.m_major,
+ matchVersion.m_version.m_minor,
+ matchVersion.m_version.m_patch + 1);
break;
}
- default: break;
+ default: break;
}
List<SemanticVersion> sortedVersions;
sortedVersions.addRange(versions, count);
// Sort into increasing values
- sortedVersions.sort([&](const SemanticVersion& a, const SemanticVersion& b) -> bool { return a < b; });
+ sortedVersions.sort(
+ [&](const SemanticVersion& a, const SemanticVersion& b) -> bool { return a < b; });
Index startIndex = 0;
- for (; startIndex < count && sortedVersions[startIndex] < start; ++startIndex);
+ for (; startIndex < count && sortedVersions[startIndex] < start; ++startIndex)
+ ;
Index endIndex = startIndex;
- for (; endIndex < count && sortedVersions[endIndex] < end; ++endIndex);
+ for (; endIndex < count && sortedVersions[endIndex] < end; ++endIndex)
+ ;
// If we have a span of versions, get the last in the span
if (startIndex < endIndex)
@@ -173,7 +189,7 @@ void SemanticVersion::append(StringBuilder& buf) const
return sortedVersions[startIndex - 1];
}
- // All cases should be covered, but return the last one
+ // All cases should be covered, but return the last one
return sortedVersions[count - 1];
}
@@ -181,21 +197,21 @@ void MatchSemanticVersion::append(StringBuilder& buf) const
{
switch (m_kind)
{
- default:
- case Kind::Unknown: buf << "unknown"; break;
- case Kind::Past: buf << "past"; break;
- case Kind::Future: buf << "future"; break;
- case Kind::Major:
+ default:
+ case Kind::Unknown: buf << "unknown"; break;
+ case Kind::Past: buf << "past"; break;
+ case Kind::Future: buf << "future"; break;
+ case Kind::Major:
{
buf << m_version.m_major;
break;
}
- case Kind::MajorMinor:
+ case Kind::MajorMinor:
{
buf << m_version.m_major << "." << m_version.m_minor;
break;
}
- case Kind::MajorMinorPatch:
+ case Kind::MajorMinorPatch:
{
m_version.append(buf);
break;
diff --git a/source/core/slang-semantic-version.h b/source/core/slang-semantic-version.h
index e7f10eeed..0bb467ab7 100644
--- a/source/core/slang-semantic-version.h
+++ b/source/core/slang-semantic-version.h
@@ -14,13 +14,15 @@ struct SemanticVersion
typedef uint64_t IntegerType;
- SemanticVersion():m_major(0), m_minor(0), m_patch(0) {}
+ SemanticVersion()
+ : m_major(0), m_minor(0), m_patch(0)
+ {
+ }
- SemanticVersion(int inMajor, int inMinor = 0, int inPatch = 0):
- m_major(uint16_t(inMajor)),
- m_minor(uint16_t(inMinor)),
- m_patch(uint32_t(inPatch))
- {}
+ SemanticVersion(int inMajor, int inMinor = 0, int inPatch = 0)
+ : m_major(uint16_t(inMajor)), m_minor(uint16_t(inMinor)), m_patch(uint32_t(inPatch))
+ {
+ }
void reset()
{
@@ -29,28 +31,34 @@ struct SemanticVersion
m_patch = 0;
}
- /// All zeros means nothing is set
+ /// All zeros means nothing is set
bool isSet() const { return m_major || m_minor || m_patch; }
- IntegerType toInteger() const { return (IntegerType(m_major) << 48) | (IntegerType(m_minor) << 32) | m_patch; }
+ IntegerType toInteger() const
+ {
+ return (IntegerType(m_major) << 48) | (IntegerType(m_minor) << 32) | m_patch;
+ }
void setFromInteger(IntegerType v)
{
set(int(v >> 48), int((v >> 32) & 0xffff), int(v & 0xffffffff));
}
void set(int major, int minor, int patch = 0)
{
- SLANG_ASSERT(major >= 0 && minor >=0 && patch >= 0);
+ SLANG_ASSERT(major >= 0 && minor >= 0 && patch >= 0);
m_major = uint16_t(major);
m_minor = uint16_t(minor);
m_patch = uint32_t(patch);
}
- /// Get hash value
+ /// Get hash value
HashCode getHashCode() const { return Slang::getHashCode(toInteger()); }
static SlangResult parse(const UnownedStringSlice& value, SemanticVersion& outVersion);
- static SlangResult parse(const UnownedStringSlice& value, char separatorChar, SemanticVersion& outVersion);
+ static SlangResult parse(
+ const UnownedStringSlice& value,
+ char separatorChar,
+ SemanticVersion& outVersion);
static ThisType getEarliest(const ThisType* versions, Count count);
static ThisType getLatest(const ThisType* versions, Count count);
@@ -68,7 +76,7 @@ struct SemanticVersion
uint16_t m_major;
uint16_t m_minor;
- uint32_t m_patch; ///< Patch number. Can actually be quite large for some code bases.
+ uint32_t m_patch; ///< Patch number. Can actually be quite large for some code bases.
};
/* Adds to the semantic versioning information for an incomplete version that can be matched */
@@ -78,41 +86,64 @@ struct MatchSemanticVersion
enum class Kind
{
- Unknown, ///< Not known
- Past, ///< Some unknown past version
- Future, ///< Some future unknown version
- Major, ///< Major version is defined (minor is in effect undefined)
- MajorMinor, ///< Major and minor version are defined
- MajorMinorPatch, ///< All elements of semantic version are defined
+ Unknown, ///< Not known
+ Past, ///< Some unknown past version
+ Future, ///< Some future unknown version
+ Major, ///< Major version is defined (minor is in effect undefined)
+ MajorMinor, ///< Major and minor version are defined
+ MajorMinorPatch, ///< All elements of semantic version are defined
};
- /// True if has a complete version
+ /// True if has a complete version
bool hasCompleteVersion() const { return m_kind == Kind::MajorMinorPatch; }
- /// True if has some version information
+ /// True if has some version information
bool hasVersion() const { return Index(m_kind) >= Index(Kind::Major); }
- void set(Index major) { m_kind = Kind::Major; m_version = SemanticVersion(int(major), 0, 0); }
- void set(Index major, Index minor) { m_kind = Kind::MajorMinor; m_version = SemanticVersion(int(major), int(minor), 0); }
- void set(Index major, Index minor, Index patch) { m_kind = Kind::MajorMinorPatch; m_version = SemanticVersion(int(major), int(minor), int(patch)); }
+ void set(Index major)
+ {
+ m_kind = Kind::Major;
+ m_version = SemanticVersion(int(major), 0, 0);
+ }
+ void set(Index major, Index minor)
+ {
+ m_kind = Kind::MajorMinor;
+ m_version = SemanticVersion(int(major), int(minor), 0);
+ }
+ void set(Index major, Index minor, Index patch)
+ {
+ m_kind = Kind::MajorMinorPatch;
+ m_version = SemanticVersion(int(major), int(minor), int(patch));
+ }
void append(StringBuilder& buf) const;
- static MatchSemanticVersion makeFuture() { MatchSemanticVersion version; version.m_kind = Kind::Future; return version; }
+ static MatchSemanticVersion makeFuture()
+ {
+ MatchSemanticVersion version;
+ version.m_kind = Kind::Future;
+ return version;
+ }
- /// Finds the 'best' version based on the versions passed.
- /// Doesn't follow strict semantic rules as will attempt to return the closest 'any' in past or future
- /// If none can be found, returns an empty semantic version
- static SemanticVersion findAnyBest(const SemanticVersion* versions, Count count, const ThisType& matchVersion);
+ /// Finds the 'best' version based on the versions passed.
+ /// Doesn't follow strict semantic rules as will attempt to return the closest 'any' in past or
+ /// future If none can be found, returns an empty semantic version
+ static SemanticVersion findAnyBest(
+ const SemanticVersion* versions,
+ Count count,
+ const ThisType& matchVersion);
- MatchSemanticVersion():m_kind(Kind::Unknown) {}
- MatchSemanticVersion(Kind kind, const SemanticVersion& version):
- m_kind(kind),
- m_version(version)
- {}
+ MatchSemanticVersion()
+ : m_kind(Kind::Unknown)
+ {
+ }
+ MatchSemanticVersion(Kind kind, const SemanticVersion& version)
+ : m_kind(kind), m_version(version)
+ {
+ }
Kind m_kind;
SemanticVersion m_version;
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-shared-library.cpp b/source/core/slang-shared-library.cpp
index 34464597c..f62591af0 100644
--- a/source/core/slang-shared-library.cpp
+++ b/source/core/slang-shared-library.cpp
@@ -1,7 +1,6 @@
#include "slang-shared-library.h"
#include "slang-com-ptr.h"
-
#include "slang-io.h"
#include "slang-string-util.h"
@@ -13,7 +12,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
-# include <unistd.h>
+#include <unistd.h>
#endif
namespace Slang
@@ -21,14 +20,19 @@ namespace Slang
/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibraryLoader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
-/* static */DefaultSharedLibraryLoader DefaultSharedLibraryLoader::s_singleton;
+/* static */ DefaultSharedLibraryLoader DefaultSharedLibraryLoader::s_singleton;
ISlangUnknown* DefaultSharedLibraryLoader::getInterface(const Guid& guid)
{
- return (guid == ISlangUnknown::getTypeGuid() || guid == ISlangSharedLibraryLoader::getTypeGuid()) ? static_cast<ISlangSharedLibraryLoader*>(this) : nullptr;
+ return (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ISlangSharedLibraryLoader::getTypeGuid())
+ ? static_cast<ISlangSharedLibraryLoader*>(this)
+ : nullptr;
}
-SlangResult DefaultSharedLibraryLoader::loadSharedLibrary(const char* path, ISlangSharedLibrary** outSharedLibrary)
+SlangResult DefaultSharedLibraryLoader::loadSharedLibrary(
+ const char* path,
+ ISlangSharedLibrary** outSharedLibrary)
{
*outSharedLibrary = nullptr;
// Try loading
@@ -38,7 +42,9 @@ SlangResult DefaultSharedLibraryLoader::loadSharedLibrary(const char* path, ISla
return SLANG_OK;
}
-SlangResult DefaultSharedLibraryLoader::loadPlatformSharedLibrary(const char* path, ISlangSharedLibrary** outSharedLibrary)
+SlangResult DefaultSharedLibraryLoader::loadPlatformSharedLibrary(
+ const char* path,
+ ISlangSharedLibrary** outSharedLibrary)
{
*outSharedLibrary = nullptr;
// Try loading
@@ -48,7 +54,11 @@ SlangResult DefaultSharedLibraryLoader::loadPlatformSharedLibrary(const char* pa
return SLANG_OK;
}
-/* static */SlangResult DefaultSharedLibraryLoader::load(ISlangSharedLibraryLoader* loader, const String& path, const String& name, ISlangSharedLibrary** outLibrary)
+/* static */ SlangResult DefaultSharedLibraryLoader::load(
+ ISlangSharedLibraryLoader* loader,
+ const String& path,
+ const String& name,
+ ISlangSharedLibrary** outLibrary)
{
if (path.getLength())
{
@@ -99,8 +109,7 @@ void* DefaultSharedLibrary::castAs(const SlangUUID& guid)
void* DefaultSharedLibrary::getInterface(const Guid& guid)
{
- if (guid == ISlangUnknown::getTypeGuid() ||
- guid == ICastable::getTypeGuid() ||
+ if (guid == ISlangUnknown::getTypeGuid() || guid == ICastable::getTypeGuid() ||
guid == ISlangSharedLibrary::getTypeGuid())
{
return static_cast<ISlangSharedLibrary*>(this);
@@ -164,4 +173,4 @@ uint64_t SharedLibraryUtils::getSharedLibraryTimestamp(void* symbolInLib)
return 0;
}
-}
+} // namespace Slang
diff --git a/source/core/slang-shared-library.h b/source/core/slang-shared-library.h
index d6c1618ec..fbc8a1d30 100644
--- a/source/core/slang-shared-library.h
+++ b/source/core/slang-shared-library.h
@@ -1,15 +1,14 @@
#ifndef SLANG_CORE_SHARED_LIBRARY_H
#define SLANG_CORE_SHARED_LIBRARY_H
-#include "slang.h"
-#include "slang-com-helper.h"
-#include "slang-com-ptr.h"
-
#include "../core/slang-com-object.h"
-#include "../core/slang-io.h"
-#include "../core/slang-platform.h"
#include "../core/slang-common.h"
#include "../core/slang-dictionary.h"
+#include "../core/slang-io.h"
+#include "../core/slang-platform.h"
+#include "slang-com-helper.h"
+#include "slang-com-ptr.h"
+#include "slang.h"
namespace Slang
{
@@ -17,27 +16,30 @@ namespace Slang
class DefaultSharedLibraryLoader : public ISlangSharedLibraryLoader
{
public:
-
- // ISlangUnknown
+ // ISlangUnknown
// override ref counting, as DefaultSharedLibraryLoader is singleton
- SLANG_IUNKNOWN_QUERY_INTERFACE
+ SLANG_IUNKNOWN_QUERY_INTERFACE
SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
- SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
// ISlangSharedLibraryLoader
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadSharedLibrary(const char* path,
- ISlangSharedLibrary** outSharedLibrary) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ loadSharedLibrary(const char* path, ISlangSharedLibrary** outSharedLibrary) SLANG_OVERRIDE;
SlangResult loadPlatformSharedLibrary(const char* path, ISlangSharedLibrary** outSharedLibrary);
- /// Get the singleton
+ /// Get the singleton
static DefaultSharedLibraryLoader* getSingleton() { return &s_singleton; }
- static SlangResult load(ISlangSharedLibraryLoader* loader, const String& path, const String& name, ISlangSharedLibrary** outLibrary);
+ static SlangResult load(
+ ISlangSharedLibraryLoader* loader,
+ const String& path,
+ const String& name,
+ ISlangSharedLibrary** outLibrary);
private:
- /// Make so not constructible
+ /// Make so not constructible
DefaultSharedLibraryLoader() {}
virtual ~DefaultSharedLibraryLoader() {}
@@ -48,28 +50,28 @@ private:
class DefaultSharedLibrary : public ISlangSharedLibrary, public ComBaseObject
{
- public:
- SLANG_CLASS_GUID(0xe7f2597b, 0xf803, 0x4b6e, { 0xaf, 0x8b, 0xcb, 0xe3, 0xa2, 0x21, 0xfd, 0x5a })
+public:
+ SLANG_CLASS_GUID(0xe7f2597b, 0xf803, 0x4b6e, {0xaf, 0x8b, 0xcb, 0xe3, 0xa2, 0x21, 0xfd, 0x5a})
// ISlangUnknown
SLANG_COM_BASE_IUNKNOWN_ALL
// ICastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
// ISlangSharedLibrary
- virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name)
+ SLANG_OVERRIDE;
- /// Ctor.
- DefaultSharedLibrary(const SharedLibrary::Handle sharedLibraryHandle):
- m_sharedLibraryHandle(sharedLibraryHandle)
+ /// Ctor.
+ DefaultSharedLibrary(const SharedLibrary::Handle sharedLibraryHandle)
+ : m_sharedLibraryHandle(sharedLibraryHandle)
{
SLANG_ASSERT(sharedLibraryHandle);
}
- /// Need virtual dtor to keep delete this happy
+ /// Need virtual dtor to keep delete this happy
virtual ~DefaultSharedLibrary();
- protected:
-
+protected:
void* getInterface(const Guid& guid);
void* getObject(const Guid& guid);
@@ -78,18 +80,19 @@ class DefaultSharedLibrary : public ISlangSharedLibrary, public ComBaseObject
class ScopeSharedLibrary : public DefaultSharedLibrary
{
-public:
+public:
typedef DefaultSharedLibrary Super;
- static ComPtr<ISlangSharedLibrary> create(const SharedLibrary::Handle sharedLibraryHandle, ISlangUnknown* scope)
+ static ComPtr<ISlangSharedLibrary> create(
+ const SharedLibrary::Handle sharedLibraryHandle,
+ ISlangUnknown* scope)
{
- return ComPtr< ISlangSharedLibrary>(new ScopeSharedLibrary(sharedLibraryHandle, scope));
+ return ComPtr<ISlangSharedLibrary>(new ScopeSharedLibrary(sharedLibraryHandle, scope));
}
/// Ctor
- ScopeSharedLibrary(const SharedLibrary::Handle sharedLibraryHandle, ISlangUnknown* scope) :
- Super(sharedLibraryHandle),
- m_scope(scope)
+ ScopeSharedLibrary(const SharedLibrary::Handle sharedLibraryHandle, ISlangUnknown* scope)
+ : Super(sharedLibraryHandle), m_scope(scope)
{
}
@@ -106,6 +109,6 @@ public:
static uint64_t getSharedLibraryTimestamp(void* symbolInLib);
};
-}
+} // namespace Slang
#endif // SLANG_SHARED_LIBRARY_H_INCLUDED
diff --git a/source/core/slang-short-list.h b/source/core/slang-short-list.h
index 66165fc72..87d52c8d7 100644
--- a/source/core/slang-short-list.h
+++ b/source/core/slang-short-list.h
@@ -1,497 +1,493 @@
#ifndef SLANG_CORE_SHORT_LIST_H
#define SLANG_CORE_SHORT_LIST_H
-#include "slang.h"
-
#include "slang-allocator.h"
-#include "slang-math.h"
#include "slang-array-view.h"
+#include "slang-math.h"
+#include "slang.h"
namespace Slang
{
- template<typename T, int shortListSize = 16, typename TAllocator = StandardAllocator>
- class ShortList
- {
- private:
- static const Index kInitialCount = 16;
- typedef ShortList<T, shortListSize, TAllocator> ThisType;
- public:
- ShortList()
- : m_buffer(nullptr), m_count(0), m_capacity(0)
+template<typename T, int shortListSize = 16, typename TAllocator = StandardAllocator>
+class ShortList
+{
+private:
+ static const Index kInitialCount = 16;
+ typedef ShortList<T, shortListSize, TAllocator> ThisType;
+
+public:
+ ShortList()
+ : m_buffer(nullptr), m_count(0), m_capacity(0)
+ {
+ }
+ template<typename... Args>
+ ShortList(const T& val, Args... args)
+ {
+ _init(val, args...);
+ }
+ ShortList(const ThisType& list)
+ : m_buffer(nullptr), m_count(0), m_capacity(0)
+ {
+ this->operator=(list);
+ }
+ ShortList(ThisType&& list)
+ : m_buffer(nullptr), m_count(0), m_capacity(0)
+ {
+ this->operator=(static_cast<ThisType&&>(list));
+ }
+ ~ShortList() { _deallocateBuffer(); }
+ template<int _otherShortListSize, typename TOtherAllocator>
+ ThisType& operator=(const ShortList<T, _otherShortListSize, TOtherAllocator>& list)
+ {
+ clearAndDeallocate();
+ addRange(list);
+ return *this;
+ }
+
+ ThisType& operator=(const ThisType& other)
+ {
+ clearAndDeallocate();
+ addRange(other);
+ return *this;
+ }
+
+ ThisType& operator=(ThisType&& list)
+ {
+ // Could just do a swap here, and memory would be freed on rhs dtor
+ _deallocateBuffer();
+ m_count = list.m_count;
+ m_capacity = list.m_capacity;
+ m_buffer = list.m_buffer;
+
+ list.m_buffer = nullptr;
+ list.m_count = 0;
+ list.m_capacity = 0;
+
+ for (Index i = 0; i < Math::Min((Index)shortListSize, m_count); i++)
+ m_shortBuffer[i] = _Move(list.m_shortBuffer[i]);
+ return *this;
+ }
+
+ struct Iterator
+ {
+ ThisType* container = nullptr;
+ Index index = -1;
+ Iterator& operator++()
{
+ ++index;
+ return *this;
}
- template<typename... Args>
- ShortList(const T& val, Args... args)
+ Iterator operator++(int)
{
- _init(val, args...);
+ Iterator rs = *this;
+ ++index;
+ return rs;
}
- ShortList(const ThisType& list)
- : m_buffer(nullptr), m_count(0), m_capacity(0)
+ Iterator& operator--()
{
- this->operator=(list);
+ --index;
+ return *this;
}
- ShortList(ThisType&& list)
- : m_buffer(nullptr), m_count(0), m_capacity(0)
+ Iterator operator--(int)
{
- this->operator=(static_cast<ThisType&&>(list));
+ Iterator rs = *this;
+ --index;
+ return rs;
}
- ~ShortList()
+ T* operator->()
{
- _deallocateBuffer();
+ SLANG_ASSERT(container);
+ return &(*container)[index];
}
- template<int _otherShortListSize, typename TOtherAllocator>
- ThisType& operator=(const ShortList<T, _otherShortListSize, TOtherAllocator>& list)
+ T& operator*()
{
- clearAndDeallocate();
- addRange(list);
- return *this;
+ SLANG_ASSERT(container);
+ return (*container)[index];
}
-
- ThisType& operator=(const ThisType& other)
+ bool operator==(Iterator other)
{
- clearAndDeallocate();
- addRange(other);
- return *this;
+ return container == other.container && index == other.index;
}
-
- ThisType& operator=(ThisType&& list)
+ bool operator!=(Iterator other)
{
- // Could just do a swap here, and memory would be freed on rhs dtor
- _deallocateBuffer();
- m_count = list.m_count;
- m_capacity = list.m_capacity;
- m_buffer = list.m_buffer;
+ return index != other.index || container != other.container;
+ }
+ };
- list.m_buffer = nullptr;
- list.m_count = 0;
- list.m_capacity = 0;
+ Iterator begin() const
+ {
+ Iterator rs;
+ rs.container = const_cast<ThisType*>(this);
+ rs.index = 0;
+ return rs;
+ }
+ Iterator end() const
+ {
+ Iterator rs;
+ rs.container = const_cast<ThisType*>(this);
+ rs.index = m_count;
+ return rs;
+ }
- for (Index i = 0; i < Math::Min((Index)shortListSize, m_count); i++)
- m_shortBuffer[i] = _Move(list.m_shortBuffer[i]);
- return *this;
- }
+ const T& getFirst() const
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_shortBuffer[0];
+ }
- struct Iterator
- {
- ThisType* container = nullptr;
- Index index = -1;
- Iterator& operator++()
- {
- ++index;
- return *this;
- }
- Iterator operator++(int)
- {
- Iterator rs = *this;
- ++index;
- return rs;
- }
- Iterator& operator--()
- {
- --index;
- return *this;
- }
- Iterator operator--(int)
- {
- Iterator rs = *this;
- --index;
- return rs;
- }
- T* operator->()
- {
- SLANG_ASSERT(container);
- return &(*container)[index];
- }
- T& operator*()
- {
- SLANG_ASSERT(container);
- return (*container)[index];
- }
- bool operator==(Iterator other)
- {
- return container == other.container && index == other.index;
- }
- bool operator!=(Iterator other)
- {
- return index != other.index || container != other.container;
- }
- };
+ T& getFirst()
+ {
+ SLANG_ASSERT(m_count > 0);
+ return m_shortBuffer[0];
+ }
- Iterator begin() const
- {
- Iterator rs;
- rs.container = const_cast<ThisType*>(this);
- rs.index = 0;
- return rs;
- }
- Iterator end() const
- {
- Iterator rs;
- rs.container = const_cast<ThisType*>(this);
- rs.index = m_count;
- return rs;
- }
+ const T& getLast() const
+ {
+ SLANG_ASSERT(m_count > 0);
+ if (m_count <= shortListSize)
+ return m_shortBuffer[m_count - 1];
+ return m_buffer[m_count - shortListSize - 1];
+ }
- const T& getFirst() const
- {
- SLANG_ASSERT(m_count > 0);
- return m_shortBuffer[0];
- }
+ T& getLast()
+ {
+ SLANG_ASSERT(m_count > 0);
+ if (m_count <= shortListSize)
+ return m_shortBuffer[m_count - 1];
+ return m_buffer[m_count - shortListSize - 1];
+ }
- T& getFirst()
- {
- SLANG_ASSERT(m_count > 0);
- return m_shortBuffer[0];
- }
+ void removeLast()
+ {
+ SLANG_ASSERT(m_count > 0);
+ m_count--;
+ }
+
+ struct GetArrayViewResult
+ {
+ ArrayView<T> arrayView;
+ bool ownsStorage = false;
- const T& getLast() const
+ GetArrayViewResult() = default;
+ GetArrayViewResult(const GetArrayViewResult&) = delete;
+ GetArrayViewResult(GetArrayViewResult&& other)
{
- SLANG_ASSERT(m_count > 0);
- if (m_count <= shortListSize)
- return m_shortBuffer[m_count - 1];
- return m_buffer[m_count - shortListSize - 1];
+ ownsStorage = other.ownsStorage;
+ arrayView = other.arrayView;
+ other.ownsStorage = false;
}
-
- T& getLast()
+ ~GetArrayViewResult()
{
- SLANG_ASSERT(m_count > 0);
- if (m_count <= shortListSize)
- return m_shortBuffer[m_count - 1];
- return m_buffer[m_count - shortListSize - 1];
+ if (ownsStorage)
+ {
+ ThisType::_free(arrayView.m_buffer, arrayView.m_count);
+ }
}
-
- void removeLast()
+ T* getBuffer() { return arrayView.getBuffer(); }
+ };
+ inline GetArrayViewResult getArrayView() const
+ {
+ GetArrayViewResult result;
+ if (m_count > shortListSize)
{
- SLANG_ASSERT(m_count > 0);
- m_count--;
+ result.arrayView.m_buffer = ThisType::_allocate(m_count);
+ result.arrayView.m_count = m_count;
+ for (Index i = 0; i < shortListSize; i++)
+ result.arrayView.m_buffer[i] = m_shortBuffer[i];
+ for (Index i = shortListSize; i < m_count; i++)
+ result.arrayView.m_buffer[i] = m_buffer[i - shortListSize];
+ result.ownsStorage = true;
}
-
- struct GetArrayViewResult
+ else
{
- ArrayView<T> arrayView;
- bool ownsStorage = false;
+ result.arrayView.m_buffer = const_cast<T*>(&m_shortBuffer[0]);
+ result.arrayView.m_count = m_count;
+ }
+ return result;
+ }
- GetArrayViewResult() = default;
- GetArrayViewResult(const GetArrayViewResult&) = delete;
- GetArrayViewResult(GetArrayViewResult&& other)
- {
- ownsStorage = other.ownsStorage;
- arrayView = other.arrayView;
- other.ownsStorage = false;
- }
- ~GetArrayViewResult()
- {
- if (ownsStorage)
- {
- ThisType::_free(arrayView.m_buffer, arrayView.m_count);
- }
- }
- T* getBuffer() { return arrayView.getBuffer(); }
- };
- inline GetArrayViewResult getArrayView() const
+ inline GetArrayViewResult getArrayView(Index start, Index count) const
+ {
+ SLANG_ASSERT(start >= 0 && count >= 0 && start + count <= m_count);
+ GetArrayViewResult result;
+ if (start < shortListSize && start + count > shortListSize)
+ {
+ result.ownsStorage = true;
+ result.arrayView.m_count = count;
+ result.arrayView.m_buffer = ThisType::_allocate(count);
+ for (Index i = start; i < shortListSize; i++)
+ result.arrayView.m_buffer[i - start] = m_shortBuffer[i];
+ for (Index i = shortListSize; i < start + count; i++)
+ result.arrayView.m_buffer[i - start] = m_buffer[i - shortListSize];
+ return result;
+ }
+ else if (start + count <= shortListSize)
{
- GetArrayViewResult result;
- if (m_count > shortListSize)
- {
- result.arrayView.m_buffer = ThisType::_allocate(m_count);
- result.arrayView.m_count = m_count;
- for (Index i = 0; i < shortListSize; i++)
- result.arrayView.m_buffer[i] = m_shortBuffer[i];
- for (Index i = shortListSize; i < m_count; i++)
- result.arrayView.m_buffer[i] = m_buffer[i - shortListSize];
- result.ownsStorage = true;
- }
- else
- {
- result.arrayView.m_buffer = const_cast<T*>(&m_shortBuffer[0]);
- result.arrayView.m_count = m_count;
- }
+ result.ownsStorage = false;
+ result.arrayView.m_count = count;
+ result.arrayView.m_buffer = const_cast<T*>(m_shortBuffer) + start;
return result;
}
-
- inline GetArrayViewResult getArrayView(Index start, Index count) const
+ else
{
- SLANG_ASSERT(start >= 0 && count >= 0 && start + count <= m_count);
- GetArrayViewResult result;
- if (start < shortListSize && start + count > shortListSize)
- {
- result.ownsStorage = true;
- result.arrayView.m_count = count;
- result.arrayView.m_buffer = ThisType::_allocate(count);
- for (Index i = start; i < shortListSize; i++)
- result.arrayView.m_buffer[i - start] = m_shortBuffer[i];
- for (Index i = shortListSize; i < start + count; i++)
- result.arrayView.m_buffer[i - start] = m_buffer[i - shortListSize];
- return result;
- }
- else if (start + count <= shortListSize)
- {
- result.ownsStorage = false;
- result.arrayView.m_count = count;
- result.arrayView.m_buffer = const_cast<T*>(m_shortBuffer) + start;
- return result;
- }
- else
- {
- result.ownsStorage = false;
- result.arrayView.m_count = count;
- result.arrayView.m_buffer = m_buffer + start - shortListSize;
- return result;
- }
+ result.ownsStorage = false;
+ result.arrayView.m_count = count;
+ result.arrayView.m_buffer = m_buffer + start - shortListSize;
+ return result;
}
+ }
- void _maybeReserveForAdd()
+ void _maybeReserveForAdd()
+ {
+ if (m_capacity <= m_count - shortListSize)
{
- if (m_capacity <= m_count - shortListSize)
- {
- Index newBufferSize = kInitialCount;
- if (m_capacity)
- newBufferSize = (m_capacity << 1);
+ Index newBufferSize = kInitialCount;
+ if (m_capacity)
+ newBufferSize = (m_capacity << 1);
- reserveOverflowBuffer(newBufferSize);
- }
+ reserveOverflowBuffer(newBufferSize);
}
+ }
- void add(T&& obj)
+ void add(T&& obj)
+ {
+ if (m_count < shortListSize)
{
- if (m_count < shortListSize)
- {
- m_shortBuffer[m_count] = static_cast<T&&>(obj);
- m_count++;
- return;
- }
- _maybeReserveForAdd();
- m_buffer[m_count - shortListSize] = static_cast<T&&>(obj);
+ m_shortBuffer[m_count] = static_cast<T&&>(obj);
m_count++;
+ return;
}
+ _maybeReserveForAdd();
+ m_buffer[m_count - shortListSize] = static_cast<T&&>(obj);
+ m_count++;
+ }
- void add(const T& obj)
+ void add(const T& obj)
+ {
+ if (m_count < shortListSize)
{
- if (m_count < shortListSize)
- {
- m_shortBuffer[m_count] = obj;
- m_count++;
- return;
- }
- _maybeReserveForAdd();
- m_buffer[m_count - shortListSize] = obj;
+ m_shortBuffer[m_count] = obj;
m_count++;
+ return;
}
+ _maybeReserveForAdd();
+ m_buffer[m_count - shortListSize] = obj;
+ m_count++;
+ }
- Index getCount() const { return m_count; }
+ Index getCount() const { return m_count; }
- void addRange(const T* vals, Index n)
- {
- for (Index i = 0; i < n; i++)
- add(vals[i]);
- }
+ void addRange(const T* vals, Index n)
+ {
+ for (Index i = 0; i < n; i++)
+ add(vals[i]);
+ }
- void addRange(ArrayView<T> list) { addRange(list.m_buffer, list.m_count); }
+ void addRange(ArrayView<T> list) { addRange(list.m_buffer, list.m_count); }
- void addRange(ConstArrayView<T> list) { addRange(list.m_buffer, list.m_count); }
+ void addRange(ConstArrayView<T> list) { addRange(list.m_buffer, list.m_count); }
- template<int _otherShortListSize, typename TOtherAllocator>
- void addRange(const ShortList<T, _otherShortListSize, TOtherAllocator>& list)
- {
- for (Index i = 0; i < list.getCount(); i++)
- add(list[i]);
- }
+ template<int _otherShortListSize, typename TOtherAllocator>
+ void addRange(const ShortList<T, _otherShortListSize, TOtherAllocator>& list)
+ {
+ for (Index i = 0; i < list.getCount(); i++)
+ add(list[i]);
+ }
- void fastRemove(const T& val)
+ void fastRemove(const T& val)
+ {
+ Index idx = indexOf(val);
+ if (idx >= 0)
{
- Index idx = indexOf(val);
- if (idx >= 0)
- {
- fastRemoveAt(idx);
- }
+ fastRemoveAt(idx);
}
+ }
- void fastRemoveAt(Index idx)
- {
- SLANG_ASSERT(idx >= 0 && idx < m_count);
+ void fastRemoveAt(Index idx)
+ {
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
- if (idx != m_count - 1)
- {
- (*this)[idx] = _Move(getLast());
- }
- m_count--;
+ if (idx != m_count - 1)
+ {
+ (*this)[idx] = _Move(getLast());
}
+ m_count--;
+ }
- void clear() { m_count = 0; }
+ void clear() { m_count = 0; }
- void clearAndDeallocate()
- {
- _deallocateBuffer();
- m_count = m_capacity = 0;
- }
+ void clearAndDeallocate()
+ {
+ _deallocateBuffer();
+ m_count = m_capacity = 0;
+ }
- void reserveOverflowBuffer(Index size)
+ void reserveOverflowBuffer(Index size)
+ {
+ if (size > m_capacity)
{
- if (size > m_capacity)
+ T* newBuffer = _allocate(size);
+ if (m_capacity)
{
- T* newBuffer = _allocate(size);
- if (m_capacity)
+ for (Index i = 0; i < m_count - shortListSize; i++)
+ newBuffer[i] = static_cast<T&&>(m_buffer[i]);
+
+ // Default-initialize the remaining elements
+ for (Index i = m_count - shortListSize; i < size; i++)
{
- for (Index i = 0; i < m_count - shortListSize; i++)
- newBuffer[i] = static_cast<T&&>(m_buffer[i]);
-
- // Default-initialize the remaining elements
- for (Index i = m_count - shortListSize; i < size; i++)
- {
- new(newBuffer + i) T();
- }
- _deallocateBuffer();
+ new (newBuffer + i) T();
}
- m_buffer = newBuffer;
- m_capacity = size;
+ _deallocateBuffer();
}
+ m_buffer = newBuffer;
+ m_capacity = size;
}
+ }
- void setCount(Index count)
- {
- if (count > shortListSize)
- reserveOverflowBuffer(count - shortListSize);
- m_count = count;
- }
+ void setCount(Index count)
+ {
+ if (count > shortListSize)
+ reserveOverflowBuffer(count - shortListSize);
+ m_count = count;
+ }
- void unsafeShrinkToCount(Index count) { m_count = count; }
+ void unsafeShrinkToCount(Index count) { m_count = count; }
- void compress()
+ void compress()
+ {
+ if (m_capacity > m_count - shortListSize && m_count > shortListSize)
{
- if (m_capacity > m_count - shortListSize && m_count > shortListSize)
+ T* newBuffer = nullptr;
+ if (m_count > shortListSize)
{
- T* newBuffer = nullptr;
- if (m_count > shortListSize)
- {
- newBuffer = _allocate(m_count - shortListSize);
- for (Index i = shortListSize; i < m_count; i++)
- newBuffer[i - shortListSize] = static_cast<T&&>(m_buffer[i - shortListSize]);
- }
- _deallocateBuffer();
- m_buffer = newBuffer;
- m_capacity = m_count - shortListSize;
+ newBuffer = _allocate(m_count - shortListSize);
+ for (Index i = shortListSize; i < m_count; i++)
+ newBuffer[i - shortListSize] = static_cast<T&&>(m_buffer[i - shortListSize]);
}
+ _deallocateBuffer();
+ m_buffer = newBuffer;
+ m_capacity = m_count - shortListSize;
}
+ }
- SLANG_FORCE_INLINE const T& operator [](Index idx) const
- {
- SLANG_ASSERT(idx >= 0 && idx < m_count);
- return (idx < shortListSize) ?
- m_shortBuffer[idx] : m_buffer[idx - shortListSize];
- }
+ SLANG_FORCE_INLINE const T& operator[](Index idx) const
+ {
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
+ return (idx < shortListSize) ? m_shortBuffer[idx] : m_buffer[idx - shortListSize];
+ }
- SLANG_FORCE_INLINE T& operator [](Index idx)
- {
- SLANG_ASSERT(idx >= 0 && idx < m_count);
- return (idx < shortListSize) ?
- m_shortBuffer[idx] : m_buffer[idx - shortListSize];
- }
+ SLANG_FORCE_INLINE T& operator[](Index idx)
+ {
+ SLANG_ASSERT(idx >= 0 && idx < m_count);
+ return (idx < shortListSize) ? m_shortBuffer[idx] : m_buffer[idx - shortListSize];
+ }
- template<typename Func>
- Index findFirstIndex(const Func& predicate) const
+ template<typename Func>
+ Index findFirstIndex(const Func& predicate) const
+ {
+ for (Index i = 0; i < Math::Min(m_count, (Index)shortListSize); i++)
{
- for (Index i = 0; i < Math::Min(m_count, (Index)shortListSize); i++)
- {
- if (predicate(m_shortBuffer[i]))
- return i;
- }
- for (Index i = shortListSize; i < m_count; i++)
- {
- if (predicate(m_buffer[i - shortListSize]))
- return i;
- }
- return -1;
+ if (predicate(m_shortBuffer[i]))
+ return i;
}
-
- template<typename T2>
- Index indexOf(const T2& val) const
+ for (Index i = shortListSize; i < m_count; i++)
{
- for (Index i = 0; i < Math::Min(m_count, (Index)shortListSize); i++)
- {
- if (m_shortBuffer[i] == val)
- return i;
- }
- for (Index i = shortListSize; i < m_count; i++)
- {
- if (m_buffer[i - shortListSize] == val)
- return i;
- }
- return -1;
+ if (predicate(m_buffer[i - shortListSize]))
+ return i;
}
+ return -1;
+ }
- template<typename Func>
- Index findLastIndex(const Func& predicate) const
+ template<typename T2>
+ Index indexOf(const T2& val) const
+ {
+ for (Index i = 0; i < Math::Min(m_count, (Index)shortListSize); i++)
{
- for (Index i = m_count - 1; i >= shortListSize; i--)
- {
- if (predicate(m_buffer[i - shortListSize]))
- return i;
- }
- for (Index i = Math::Min((Index)shortListSize, m_count) - 1; i >= 0; i--)
- {
- if (predicate(m_shortBuffer[i]))
- return i;
- }
- return -1;
+ if (m_shortBuffer[i] == val)
+ return i;
}
-
- template<typename T2>
- Index lastIndexOf(const T2& val) const
+ for (Index i = shortListSize; i < m_count; i++)
{
- for (Index i = m_count - 1; i >= shortListSize; i--)
- {
- if (m_buffer[i - shortListSize] == val)
- return i;
- }
- for (Index i = Math::Min((Index)shortListSize, m_count) - 1; i >= 0; i--)
- {
- if (m_shortBuffer[i] == val)
- return i;
- }
- return -1;
+ if (m_buffer[i - shortListSize] == val)
+ return i;
}
+ return -1;
+ }
- bool contains(const T& val) const { return indexOf(val) != Index(-1); }
-
- template <typename IterateFunc>
- void forEach(IterateFunc f) const
+ template<typename Func>
+ Index findLastIndex(const Func& predicate) const
+ {
+ for (Index i = m_count - 1; i >= shortListSize; i--)
{
- for (Index i = 0; i < m_count; i++)
- f(m_buffer[i]);
+ if (predicate(m_buffer[i - shortListSize]))
+ return i;
}
-
- private:
- T* m_buffer = nullptr; ///< A new T[N] allocated buffer. NOTE! All elements up to capacity are in some valid form for T.
- Index m_capacity = 0; ///< The total capacity of elements in m_buffer
- Index m_count = 0; ///< The amount of elements
- T m_shortBuffer[shortListSize];
-
- void _deallocateBuffer()
+ for (Index i = Math::Min((Index)shortListSize, m_count) - 1; i >= 0; i--)
{
- if (m_buffer)
- {
- AllocateMethod<T, TAllocator>::deallocateArray(m_buffer, m_capacity);
- m_buffer = nullptr;
- }
+ if (predicate(m_shortBuffer[i]))
+ return i;
}
- static inline T* _allocate(Index count)
+ return -1;
+ }
+
+ template<typename T2>
+ Index lastIndexOf(const T2& val) const
+ {
+ for (Index i = m_count - 1; i >= shortListSize; i--)
{
- return AllocateMethod<T, TAllocator>::allocateArray(count);
+ if (m_buffer[i - shortListSize] == val)
+ return i;
}
- static inline void _free(T* ptr, Index count)
+ for (Index i = Math::Min((Index)shortListSize, m_count) - 1; i >= 0; i--)
{
- return AllocateMethod<T, TAllocator>::deallocateArray(ptr, count);
+ if (m_shortBuffer[i] == val)
+ return i;
}
+ return -1;
+ }
- template<typename... Args>
- void _init(const T& val, Args... args)
+ bool contains(const T& val) const { return indexOf(val) != Index(-1); }
+
+ template<typename IterateFunc>
+ void forEach(IterateFunc f) const
+ {
+ for (Index i = 0; i < m_count; i++)
+ f(m_buffer[i]);
+ }
+
+private:
+ T* m_buffer = nullptr; ///< A new T[N] allocated buffer. NOTE! All elements up to capacity are
+ ///< in some valid form for T.
+ Index m_capacity = 0; ///< The total capacity of elements in m_buffer
+ Index m_count = 0; ///< The amount of elements
+ T m_shortBuffer[shortListSize];
+
+ void _deallocateBuffer()
+ {
+ if (m_buffer)
{
- add(val);
- _init(args...);
+ AllocateMethod<T, TAllocator>::deallocateArray(m_buffer, m_capacity);
+ m_buffer = nullptr;
}
+ }
+ static inline T* _allocate(Index count)
+ {
+ return AllocateMethod<T, TAllocator>::allocateArray(count);
+ }
+ static inline void _free(T* ptr, Index count)
+ {
+ return AllocateMethod<T, TAllocator>::deallocateArray(ptr, count);
+ }
- void _init() {}
- };
-}
+ template<typename... Args>
+ void _init(const T& val, Args... args)
+ {
+ add(val);
+ _init(args...);
+ }
+
+ void _init() {}
+};
+} // namespace Slang
#endif
diff --git a/source/core/slang-signal.cpp b/source/core/slang-signal.cpp
index 5f53cba93..1600183e7 100644
--- a/source/core/slang-signal.cpp
+++ b/source/core/slang-signal.cpp
@@ -1,7 +1,6 @@
#include "slang-signal.h"
#include "slang-exception.h"
-
#include "stdio.h"
namespace Slang
@@ -11,13 +10,13 @@ static const char* _getSignalTypeAsText(SignalType type)
{
switch (type)
{
- case SignalType::AssertFailure: return "assert failure";
- case SignalType::Unimplemented: return "unimplemented";
- case SignalType::Unreachable: return "hit unreachable code";
- case SignalType::Unexpected: return "unexpected";
- case SignalType::InvalidOperation: return "invalid operation";
- case SignalType::AbortCompilation: return "abort compilation";
- default: return "unhandled";
+ case SignalType::AssertFailure: return "assert failure";
+ case SignalType::Unimplemented: return "unimplemented";
+ case SignalType::Unreachable: return "hit unreachable code";
+ case SignalType::Unexpected: return "unexpected";
+ case SignalType::InvalidOperation: return "invalid operation";
+ case SignalType::AbortCompilation: return "abort compilation";
+ default: return "unhandled";
}
}
@@ -30,7 +29,7 @@ String _getMessage(SignalType type, char const* message)
{
buf << ": " << message;
}
-
+
return buf.produceString();
}
@@ -39,7 +38,7 @@ String _getMessage(SignalType type, char const* message)
[[noreturn]] void handleSignal(SignalType type, char const* message)
{
StringBuilder buf;
- const char*const typeText = _getSignalTypeAsText(type);
+ const char* const typeText = _getSignalTypeAsText(type);
buf << typeText << ": " << message;
// Can be useful to enable during debug when problem is on CI
@@ -51,14 +50,14 @@ String _getMessage(SignalType type, char const* message)
#if SLANG_HAS_EXCEPTIONS
switch (type)
{
- case SignalType::InvalidOperation: throw InvalidOperationException(_getMessage(type, message));
- case SignalType::AbortCompilation: throw AbortCompilationException(_getMessage(type, message));
- default: throw InternalError(_getMessage(type, message));
+ case SignalType::InvalidOperation: throw InvalidOperationException(_getMessage(type, message));
+ case SignalType::AbortCompilation: throw AbortCompilationException(_getMessage(type, message));
+ default: throw InternalError(_getMessage(type, message));
}
#else
- // Attempt to drop out into the debugger. If a debugger isn't attached this will likely crash - which is probably the best
- // we can do.
-
+ // Attempt to drop out into the debugger. If a debugger isn't attached this will likely crash -
+ // which is probably the best we can do.
+
SLANG_BREAKPOINT(0);
// 'panic'. Exit with an error code as we can't throw or catch.
@@ -66,4 +65,4 @@ String _getMessage(SignalType type, char const* message)
#endif
}
-}
+} // namespace Slang
diff --git a/source/core/slang-signal.h b/source/core/slang-signal.h
index 759581ee2..356ae42f6 100644
--- a/source/core/slang-signal.h
+++ b/source/core/slang-signal.h
@@ -20,17 +20,13 @@ enum class SignalType
// Note that message can be passed as nullptr for no message.
[[noreturn]] void handleSignal(SignalType type, char const* message);
-#define SLANG_UNEXPECTED(reason) \
- ::Slang::handleSignal(::Slang::SignalType::Unexpected, reason)
+#define SLANG_UNEXPECTED(reason) ::Slang::handleSignal(::Slang::SignalType::Unexpected, reason)
-#define SLANG_UNIMPLEMENTED_X(what) \
- ::Slang::handleSignal(::Slang::SignalType::Unimplemented, what)
+#define SLANG_UNIMPLEMENTED_X(what) ::Slang::handleSignal(::Slang::SignalType::Unimplemented, what)
-#define SLANG_UNREACHABLE(msg) \
- ::Slang::handleSignal(::Slang::SignalType::Unreachable, msg)
+#define SLANG_UNREACHABLE(msg) ::Slang::handleSignal(::Slang::SignalType::Unreachable, msg)
-#define SLANG_ASSERT_FAILURE(msg) \
- ::Slang::handleSignal(::Slang::SignalType::AssertFailure, msg)
+#define SLANG_ASSERT_FAILURE(msg) ::Slang::handleSignal(::Slang::SignalType::AssertFailure, msg)
#define SLANG_INVALID_OPERATION(msg) \
::Slang::handleSignal(::Slang::SignalType::InvalidOperation, msg)
@@ -39,6 +35,6 @@ enum class SignalType
::Slang::handleSignal(::Slang::SignalType::AbortCompilation, msg)
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-smart-pointer.h b/source/core/slang-smart-pointer.h
index a45f7a8ad..46070f0b8 100644
--- a/source/core/slang-smart-pointer.h
+++ b/source/core/slang-smart-pointer.h
@@ -6,118 +6,124 @@
#include "slang-type-traits.h"
#include "slang.h"
-#include "slang.h"
-
namespace Slang
{
- // Base class for all reference-counted objects
- class SLANG_RT_API RefObject
+// Base class for all reference-counted objects
+class SLANG_RT_API RefObject
+{
+private:
+ UInt referenceCount;
+
+public:
+ RefObject()
+ : referenceCount(0)
{
- private:
- UInt referenceCount;
+ }
- public:
- RefObject()
- : referenceCount(0)
- {}
+ RefObject(const RefObject&)
+ : referenceCount(0)
+ {
+ }
- RefObject(const RefObject &)
- : referenceCount(0)
- {}
+ RefObject& operator=(const RefObject&) { return *this; }
- RefObject& operator=(const RefObject&) { return *this; }
+ virtual ~RefObject() {}
- virtual ~RefObject()
- {}
+ UInt addReference() { return ++referenceCount; }
- UInt addReference()
- {
- return ++referenceCount;
- }
+ UInt decreaseReference() { return --referenceCount; }
- UInt decreaseReference()
+ UInt releaseReference()
+ {
+ SLANG_ASSERT(referenceCount != 0);
+ if (--referenceCount == 0)
{
- return --referenceCount;
+ delete this;
+ return 0;
}
+ return referenceCount;
+ }
- UInt releaseReference()
- {
- SLANG_ASSERT(referenceCount != 0);
- if(--referenceCount == 0)
- {
- delete this;
- return 0;
- }
- return referenceCount;
- }
+ bool isUniquelyReferenced()
+ {
+ SLANG_ASSERT(referenceCount != 0);
+ return referenceCount == 1;
+ }
- bool isUniquelyReferenced()
- {
- SLANG_ASSERT(referenceCount != 0);
- return referenceCount == 1;
- }
+ UInt debugGetReferenceCount() { return referenceCount; }
+};
- UInt debugGetReferenceCount()
- {
- return referenceCount;
- }
- };
+SLANG_FORCE_INLINE void addReference(RefObject* obj)
+{
+ if (obj)
+ obj->addReference();
+}
- SLANG_FORCE_INLINE void addReference(RefObject* obj)
+SLANG_FORCE_INLINE void releaseReference(RefObject* obj)
+{
+ if (obj)
+ obj->releaseReference();
+}
+
+// For straight dynamic cast.
+// Use instead of dynamic_cast as it allows for replacement without using Rtti in the future
+template<typename T>
+SLANG_FORCE_INLINE T* dynamicCast(RefObject* obj)
+{
+ return dynamic_cast<T*>(obj);
+}
+template<typename T>
+SLANG_FORCE_INLINE const T* dynamicCast(const RefObject* obj)
+{
+ return dynamic_cast<const T*>(obj);
+}
+
+// Like a dynamicCast, but allows a type to implement a specific implementation that is suitable for
+// it
+template<typename T>
+SLANG_FORCE_INLINE T* as(RefObject* obj)
+{
+ return dynamicCast<T>(obj);
+}
+template<typename T>
+SLANG_FORCE_INLINE const T* as(const RefObject* obj)
+{
+ return dynamicCast<T>(obj);
+}
+
+// "Smart" pointer to a reference-counted object
+template<typename T>
+struct SLANG_RT_API RefPtr
+{
+ RefPtr()
+ : pointer(nullptr)
{
- if(obj) obj->addReference();
}
- SLANG_FORCE_INLINE void releaseReference(RefObject* obj)
+ RefPtr(T* p)
+ : pointer(p)
{
- if(obj) obj->releaseReference();
+ addReference(p);
}
- // For straight dynamic cast.
- // Use instead of dynamic_cast as it allows for replacement without using Rtti in the future
- template <typename T>
- SLANG_FORCE_INLINE T* dynamicCast(RefObject* obj) { return dynamic_cast<T*>(obj); }
- template <typename T>
- SLANG_FORCE_INLINE const T* dynamicCast(const RefObject* obj) { return dynamic_cast<const T*>(obj); }
-
- // Like a dynamicCast, but allows a type to implement a specific implementation that is suitable for it
- template <typename T>
- SLANG_FORCE_INLINE T* as(RefObject* obj) { return dynamicCast<T>(obj); }
- template <typename T>
- SLANG_FORCE_INLINE const T* as(const RefObject* obj) { return dynamicCast<T>(obj); }
-
- // "Smart" pointer to a reference-counted object
- template<typename T> struct SLANG_RT_API RefPtr
+ RefPtr(RefPtr<T> const& p)
+ : pointer(p.pointer)
{
- RefPtr()
- : pointer(nullptr)
- {}
-
- RefPtr(T* p)
- : pointer(p)
- {
- addReference(p);
- }
-
- RefPtr(RefPtr<T> const& p)
- : pointer(p.pointer)
- {
- addReference(p.pointer);
- }
+ addReference(p.pointer);
+ }
- RefPtr(RefPtr<T>&& p)
- : pointer(p.pointer)
- {
- p.pointer = nullptr;
- }
+ RefPtr(RefPtr<T>&& p)
+ : pointer(p.pointer)
+ {
+ p.pointer = nullptr;
+ }
- template <typename U>
- RefPtr(RefPtr<U> const& p,
- typename EnableIf<IsConvertible<T*, U*>::Value, void>::type * = 0)
- : pointer(static_cast<U*>(p))
- {
- addReference(static_cast<U*>(p));
- }
+ template<typename U>
+ RefPtr(RefPtr<U> const& p, typename EnableIf<IsConvertible<T*, U*>::Value, void>::type* = 0)
+ : pointer(static_cast<U*>(p))
+ {
+ addReference(static_cast<U*>(p));
+ }
#if 0
void operator=(T* p)
@@ -129,226 +135,202 @@ namespace Slang
}
#endif
- void operator=(RefPtr<T> const& p)
- {
- T* old = pointer;
- addReference(p.pointer);
- pointer = p.pointer;
- releaseReference(old);
- }
+ void operator=(RefPtr<T> const& p)
+ {
+ T* old = pointer;
+ addReference(p.pointer);
+ pointer = p.pointer;
+ releaseReference(old);
+ }
- void operator=(RefPtr<T>&& p)
- {
- T* old = pointer;
- pointer = p.pointer;
- p.pointer = old;
- }
+ void operator=(RefPtr<T>&& p)
+ {
+ T* old = pointer;
+ pointer = p.pointer;
+ p.pointer = old;
+ }
- template <typename U>
- typename EnableIf<IsConvertible<T*, U*>::value, void>::type
- operator=(RefPtr<U> const& p)
- {
- T* old = pointer;
- addReference(p.pointer);
- pointer = p.pointer;
- releaseReference(old);
- }
+ template<typename U>
+ typename EnableIf<IsConvertible<T*, U*>::value, void>::type operator=(RefPtr<U> const& p)
+ {
+ T* old = pointer;
+ addReference(p.pointer);
+ pointer = p.pointer;
+ releaseReference(old);
+ }
- HashCode getHashCode() const
- {
- // Note: We need a `RefPtr<T>` to hash the same as a `T*`,
- // so that a `T*` can be used as a key in a dictionary with
- // `RefPtr<T>` keys, and vice versa.
- //
- return Slang::getHashCode(pointer);
- }
+ HashCode getHashCode() const
+ {
+ // Note: We need a `RefPtr<T>` to hash the same as a `T*`,
+ // so that a `T*` can be used as a key in a dictionary with
+ // `RefPtr<T>` keys, and vice versa.
+ //
+ return Slang::getHashCode(pointer);
+ }
- bool operator==(const T * ptr) const
- {
- return pointer == ptr;
- }
+ bool operator==(const T* ptr) const { return pointer == ptr; }
- bool operator!=(const T * ptr) const
- {
- return pointer != ptr;
- }
+ bool operator!=(const T* ptr) const { return pointer != ptr; }
- bool operator==(RefPtr<T> const& ptr) const
- {
- return pointer == ptr.pointer;
- }
+ bool operator==(RefPtr<T> const& ptr) const { return pointer == ptr.pointer; }
- bool operator!=(RefPtr<T> const& ptr) const
- {
- return pointer != ptr.pointer;
- }
+ bool operator!=(RefPtr<T> const& ptr) const { return pointer != ptr.pointer; }
- template<typename U>
- RefPtr<U> dynamicCast() const
- {
- return RefPtr<U>(Slang::dynamicCast<U>(pointer));
- }
+ template<typename U>
+ RefPtr<U> dynamicCast() const
+ {
+ return RefPtr<U>(Slang::dynamicCast<U>(pointer));
+ }
- template<typename U>
- RefPtr<U> as() const
- {
- return RefPtr<U>(Slang::as<U>(pointer));
- }
+ template<typename U>
+ RefPtr<U> as() const
+ {
+ return RefPtr<U>(Slang::as<U>(pointer));
+ }
- template <typename U>
- bool is() const { return Slang::as<U>(pointer) != nullptr; }
+ template<typename U>
+ bool is() const
+ {
+ return Slang::as<U>(pointer) != nullptr;
+ }
- ~RefPtr()
- {
- releaseReference(static_cast<Slang::RefObject*>(pointer));
- }
+ ~RefPtr() { releaseReference(static_cast<Slang::RefObject*>(pointer)); }
- T& operator*() const
- {
- return *pointer;
- }
+ T& operator*() const { return *pointer; }
- T* operator->() const
- {
- return pointer;
- }
+ T* operator->() const { return pointer; }
- T * Ptr() const
- {
- return pointer;
- }
+ T* Ptr() const { return pointer; }
- T* get() const
- {
- return pointer;
- }
+ T* get() const { return pointer; }
- operator T*() const
- {
- return pointer;
- }
+ operator T*() const { return pointer; }
- void attach(T* p)
- {
- T* old = pointer;
- pointer = p;
- releaseReference(old);
- }
+ void attach(T* p)
+ {
+ T* old = pointer;
+ pointer = p;
+ releaseReference(old);
+ }
- T* detach()
- {
- auto rs = pointer;
- pointer = nullptr;
- return rs;
- }
+ T* detach()
+ {
+ auto rs = pointer;
+ pointer = nullptr;
+ return rs;
+ }
- void swapWith(RefPtr<T>& rhs)
- {
- auto rhsPtr = rhs.pointer;
- rhs.pointer = pointer;
- pointer = rhsPtr;
- }
+ void swapWith(RefPtr<T>& rhs)
+ {
+ auto rhsPtr = rhs.pointer;
+ rhs.pointer = pointer;
+ pointer = rhsPtr;
+ }
- SLANG_FORCE_INLINE void setNull()
- {
- releaseReference(pointer);
- pointer = nullptr;
- }
+ SLANG_FORCE_INLINE void setNull()
+ {
+ releaseReference(pointer);
+ pointer = nullptr;
+ }
- /// Get ready for writing (nulls contents)
- SLANG_FORCE_INLINE T** writeRef() { *this = nullptr; return &pointer; }
+ /// Get ready for writing (nulls contents)
+ SLANG_FORCE_INLINE T** writeRef()
+ {
+ *this = nullptr;
+ return &pointer;
+ }
- /// Get for read access
- SLANG_FORCE_INLINE T*const* readRef() const { return &pointer; }
+ /// Get for read access
+ SLANG_FORCE_INLINE T* const* readRef() const { return &pointer; }
- private:
- T* pointer;
- };
+private:
+ T* pointer;
+};
- // Helper type for implementing weak pointers. The object being pointed at weakly creates a WeakSink object
- // that other objects can reference and share. When the object is destroyed it detaches the sink
- // doing so will make other users call to 'get' return null. Thus any user of the WeakSink, must check if the weakly pointed to
- // things pointer is nullptr before using.
- template <typename T>
- class WeakSink : public RefObject
+// Helper type for implementing weak pointers. The object being pointed at weakly creates a WeakSink
+// object that other objects can reference and share. When the object is destroyed it detaches the
+// sink doing so will make other users call to 'get' return null. Thus any user of the WeakSink,
+// must check if the weakly pointed to things pointer is nullptr before using.
+template<typename T>
+class WeakSink : public RefObject
+{
+public:
+ WeakSink(T* ptr)
+ : m_ptr(ptr)
{
- public:
- WeakSink(T* ptr):
- m_ptr(ptr)
- {
- }
+ }
- SLANG_FORCE_INLINE T* get() const { return m_ptr; }
- SLANG_FORCE_INLINE void detach() { m_ptr = nullptr; }
+ SLANG_FORCE_INLINE T* get() const { return m_ptr; }
+ SLANG_FORCE_INLINE void detach() { m_ptr = nullptr; }
- private:
- T* m_ptr;
- };
+private:
+ T* m_ptr;
+};
- // A pointer that can be transformed to hold either a weak reference or a strong reference.
- template<typename T>
- class TransformablePtr
- {
- private:
- T* m_weakPtr = nullptr;
- RefPtr<T> m_strongPtr;
+// A pointer that can be transformed to hold either a weak reference or a strong reference.
+template<typename T>
+class TransformablePtr
+{
+private:
+ T* m_weakPtr = nullptr;
+ RefPtr<T> m_strongPtr;
- public:
- TransformablePtr() = default;
- TransformablePtr(T* ptr) { *this = ptr; }
- TransformablePtr(RefPtr<T> ptr) { *this = ptr; }
- TransformablePtr(const TransformablePtr<T>& ptr) = default;
- TransformablePtr<T>& operator=(const TransformablePtr<T>& ptr) = default;
+public:
+ TransformablePtr() = default;
+ TransformablePtr(T* ptr) { *this = ptr; }
+ TransformablePtr(RefPtr<T> ptr) { *this = ptr; }
+ TransformablePtr(const TransformablePtr<T>& ptr) = default;
+ TransformablePtr<T>& operator=(const TransformablePtr<T>& ptr) = default;
- void promoteToStrongReference() { m_strongPtr = m_weakPtr; }
- void demoteToWeakReference() { m_strongPtr = nullptr; }
- bool isStrongReference() const { return m_strongPtr != nullptr; }
+ void promoteToStrongReference() { m_strongPtr = m_weakPtr; }
+ void demoteToWeakReference() { m_strongPtr = nullptr; }
+ bool isStrongReference() const { return m_strongPtr != nullptr; }
- T& operator*() const { return *m_weakPtr; }
+ T& operator*() const { return *m_weakPtr; }
- T* operator->() const { return m_weakPtr; }
+ T* operator->() const { return m_weakPtr; }
- T* Ptr() const { return m_weakPtr; }
- T* get() const { return m_weakPtr; }
+ T* Ptr() const { return m_weakPtr; }
+ T* get() const { return m_weakPtr; }
- operator T*() const { return m_weakPtr; }
- operator RefPtr<T>() const { return m_weakPtr; }
+ operator T*() const { return m_weakPtr; }
+ operator RefPtr<T>() const { return m_weakPtr; }
- TransformablePtr<T>& operator=(T* ptr)
- {
- m_weakPtr = ptr;
- m_strongPtr = ptr;
- return *this;
- }
- template<typename U>
- TransformablePtr<T>& operator=(const RefPtr<U>& ptr)
- {
- m_weakPtr = ptr.Ptr();
- m_strongPtr = ptr;
- return *this;
- }
-
- HashCode getHashCode() const
- {
- // Note: We need a `RefPtr<T>` to hash the same as a `T*`,
- // so that a `T*` can be used as a key in a dictionary with
- // `RefPtr<T>` keys, and vice versa.
- //
- return Slang::getHashCode(m_weakPtr);
- }
+ TransformablePtr<T>& operator=(T* ptr)
+ {
+ m_weakPtr = ptr;
+ m_strongPtr = ptr;
+ return *this;
+ }
+ template<typename U>
+ TransformablePtr<T>& operator=(const RefPtr<U>& ptr)
+ {
+ m_weakPtr = ptr.Ptr();
+ m_strongPtr = ptr;
+ return *this;
+ }
- bool operator==(const T* ptr) const { return m_weakPtr == ptr; }
+ HashCode getHashCode() const
+ {
+ // Note: We need a `RefPtr<T>` to hash the same as a `T*`,
+ // so that a `T*` can be used as a key in a dictionary with
+ // `RefPtr<T>` keys, and vice versa.
+ //
+ return Slang::getHashCode(m_weakPtr);
+ }
- bool operator!=(const T* ptr) const { return m_weakPtr != ptr; }
+ bool operator==(const T* ptr) const { return m_weakPtr == ptr; }
- bool operator==(RefPtr<T> const& ptr) const { return m_weakPtr == ptr.Ptr(); }
+ bool operator!=(const T* ptr) const { return m_weakPtr != ptr; }
- bool operator!=(RefPtr<T> const& ptr) const { return m_weakPtr != ptr.Ptr(); }
+ bool operator==(RefPtr<T> const& ptr) const { return m_weakPtr == ptr.Ptr(); }
- bool operator==(TransformablePtr<T> const& ptr) const { return m_weakPtr == ptr.m_weakPtr; }
+ bool operator!=(RefPtr<T> const& ptr) const { return m_weakPtr != ptr.Ptr(); }
- bool operator!=(TransformablePtr<T> const& ptr) const { return m_weakPtr != ptr.m_weakPtr; }
- };
-}
+ bool operator==(TransformablePtr<T> const& ptr) const { return m_weakPtr == ptr.m_weakPtr; }
+
+ bool operator!=(TransformablePtr<T> const& ptr) const { return m_weakPtr != ptr.m_weakPtr; }
+};
+} // namespace Slang
#endif
diff --git a/source/core/slang-stable-hash.h b/source/core/slang-stable-hash.h
index 30a47121e..b804cc194 100644
--- a/source/core/slang-stable-hash.h
+++ b/source/core/slang-stable-hash.h
@@ -6,87 +6,87 @@
namespace Slang
{
- //
- // Types
- //
+//
+// Types
+//
- struct StableHashCode64
- {
- uint64_t hash;
- explicit operator uint64_t() const { return hash; }
- bool operator==(StableHashCode64 other) const { return other.hash == hash; };
- bool operator!=(StableHashCode64 other) const { return other.hash != hash; };
- };
+struct StableHashCode64
+{
+ uint64_t hash;
+ explicit operator uint64_t() const { return hash; }
+ bool operator==(StableHashCode64 other) const { return other.hash == hash; };
+ bool operator!=(StableHashCode64 other) const { return other.hash != hash; };
+};
- struct StableHashCode32
- {
- uint32_t hash;
- explicit operator uint32_t() const { return hash; }
- bool operator==(StableHashCode32 other) const { return other.hash == hash; };
- bool operator!=(StableHashCode32 other) const { return other.hash != hash; };
- };
+struct StableHashCode32
+{
+ uint32_t hash;
+ explicit operator uint32_t() const { return hash; }
+ bool operator==(StableHashCode32 other) const { return other.hash == hash; };
+ bool operator!=(StableHashCode32 other) const { return other.hash != hash; };
+};
- /* The 'Stable' hash code functions produce hashes that must be
+/* The 'Stable' hash code functions produce hashes that must be
- * The same result for the same inputs on all targets
- * Rarely change - as their values can change the output of the Slang API/Serialization
+* The same result for the same inputs on all targets
+* Rarely change - as their values can change the output of the Slang API/Serialization
- Hash value used from the 'Stable' functions can also be used as part of serialization -
- so it is in effect part of the API.
+Hash value used from the 'Stable' functions can also be used as part of serialization -
+so it is in effect part of the API.
- In effect this means changing a 'Stable' algorithm will typically require doing a new release.
- */
- inline StableHashCode64 getStableHashCode64(const char* buffer, size_t numChars)
+In effect this means changing a 'Stable' algorithm will typically require doing a new release.
+*/
+inline StableHashCode64 getStableHashCode64(const char* buffer, size_t numChars)
+{
+ uint64_t hash = 0;
+ for (size_t i = 0; i < numChars; ++i)
{
- uint64_t hash = 0;
- for (size_t i = 0; i < numChars; ++i)
- {
- hash = uint64_t(buffer[i]) + (hash << 6) + (hash << 16) - hash;
- }
- return StableHashCode64{hash};
+ hash = uint64_t(buffer[i]) + (hash << 6) + (hash << 16) - hash;
}
+ return StableHashCode64{hash};
+}
- template<typename T>
- inline StableHashCode64 getStableHashCode64(const T& t)
- {
- static_assert(std::has_unique_object_representations_v<T>);
- return getStableHashCode64(reinterpret_cast<const char*>(&t), sizeof(T));
- }
+template<typename T>
+inline StableHashCode64 getStableHashCode64(const T& t)
+{
+ static_assert(std::has_unique_object_representations_v<T>);
+ return getStableHashCode64(reinterpret_cast<const char*>(&t), sizeof(T));
+}
- inline StableHashCode32 getStableHashCode32(const char* buffer, size_t numChars)
+inline StableHashCode32 getStableHashCode32(const char* buffer, size_t numChars)
+{
+ uint32_t hash = 0;
+ for (size_t i = 0; i < numChars; ++i)
{
- uint32_t hash = 0;
- for (size_t i = 0; i < numChars; ++i)
- {
- hash = uint32_t(buffer[i]) + (hash << 6) + (hash << 16) - hash;
- }
- return StableHashCode32{hash};
+ hash = uint32_t(buffer[i]) + (hash << 6) + (hash << 16) - hash;
}
+ return StableHashCode32{hash};
+}
- template<typename T>
- inline StableHashCode32 getStableHashCode32(const T& t)
- {
- static_assert(std::has_unique_object_representations_v<T>);
- return getStableHashCode32(reinterpret_cast<const char*>(&t), sizeof(T));
- }
+template<typename T>
+inline StableHashCode32 getStableHashCode32(const T& t)
+{
+ static_assert(std::has_unique_object_representations_v<T>);
+ return getStableHashCode32(reinterpret_cast<const char*>(&t), sizeof(T));
+}
- inline StableHashCode64 combineStableHash(StableHashCode64 h)
- {
- return h;
- }
+inline StableHashCode64 combineStableHash(StableHashCode64 h)
+{
+ return h;
+}
- inline StableHashCode32 combineStableHash(StableHashCode32 h)
- {
- return h;
- }
+inline StableHashCode32 combineStableHash(StableHashCode32 h)
+{
+ return h;
+}
- // A left fold with a mixing operation
- template<typename H, typename... Hs>
- H combineStableHash(H n, H m, Hs... args)
- {
- return combineStableHash(H{(n.hash * 16777619) ^ m.hash}, args...);
- }
+// A left fold with a mixing operation
+template<typename H, typename... Hs>
+H combineStableHash(H n, H m, Hs... args)
+{
+ return combineStableHash(H{(n.hash * 16777619) ^ m.hash}, args...);
}
+} // namespace Slang
// > Please draw a small horse in ASCII art:
//
diff --git a/source/core/slang-std-writers.cpp b/source/core/slang-std-writers.cpp
index 264f37c98..c34f1a917 100644
--- a/source/core/slang-std-writers.cpp
+++ b/source/core/slang-std-writers.cpp
@@ -8,25 +8,27 @@
namespace Slang
{
-/* static */StdWriters* StdWriters::s_singleton = nullptr;
+/* static */ StdWriters* StdWriters::s_singleton = nullptr;
-/* static */RefPtr<StdWriters> StdWriters::createDefault()
+/* static */ RefPtr<StdWriters> StdWriters::createDefault()
{
#if SLANG_WINDOWS_FAMILY
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
#endif
RefPtr<StdWriters> stdWriters(new StdWriters);
- RefPtr<FileWriter> stdError(new FileWriter(stderr, WriterFlag::AutoFlush | WriterFlag::IsUnowned));
- RefPtr<FileWriter> stdOut(new FileWriter(stdout, WriterFlag::AutoFlush | WriterFlag::IsUnowned));
+ RefPtr<FileWriter> stdError(
+ new FileWriter(stderr, WriterFlag::AutoFlush | WriterFlag::IsUnowned));
+ RefPtr<FileWriter> stdOut(
+ new FileWriter(stdout, WriterFlag::AutoFlush | WriterFlag::IsUnowned));
stdWriters->setWriter(SLANG_WRITER_CHANNEL_STD_ERROR, stdError);
stdWriters->setWriter(SLANG_WRITER_CHANNEL_STD_OUTPUT, stdOut);
-
+
return stdWriters;
}
-/* static */RefPtr<StdWriters> StdWriters::initDefaultSingleton()
+/* static */ RefPtr<StdWriters> StdWriters::initDefaultSingleton()
{
if (s_singleton)
{
@@ -37,5 +39,4 @@ namespace Slang
return defaults;
}
-}
-
+} // namespace Slang
diff --git a/source/core/slang-std-writers.h b/source/core/slang-std-writers.h
index e99b386e3..bb67d9d9c 100644
--- a/source/core/slang-std-writers.h
+++ b/source/core/slang-std-writers.h
@@ -1,41 +1,48 @@
#ifndef SLANG_CORE_STD_WRITERS_H
#define SLANG_CORE_STD_WRITERS_H
-#include "slang-writer.h"
#include "slang-com-ptr.h"
+#include "slang-writer.h"
namespace Slang
{
/* Holds standard writers for the channels */
-class StdWriters: public RefObject
+class StdWriters : public RefObject
{
public:
-
ISlangWriter* getWriter(SlangWriterChannel chan) const { return m_writers[chan]; }
void setWriter(SlangWriterChannel chan, ISlangWriter* writer) { m_writers[chan] = writer; }
- /// Flush all the set writers
+ /// Flush all the set writers
void flushWriters();
- /// Ctor
+ /// Ctor
StdWriters() {}
- /// Initialize a default context
+ /// Initialize a default context
static RefPtr<StdWriters> createDefault();
static RefPtr<StdWriters> initDefaultSingleton();
static StdWriters* getSingleton() { return s_singleton; }
- static void setSingleton(StdWriters* context) { s_singleton = context; }
+ static void setSingleton(StdWriters* context) { s_singleton = context; }
- static WriterHelper getError() { return getSingleton()->getWriter(SLANG_WRITER_CHANNEL_STD_ERROR); }
- static WriterHelper getOut() { return getSingleton()->getWriter(SLANG_WRITER_CHANNEL_STD_OUTPUT); }
- static WriterHelper getDiagnostic() { return getSingleton()->getWriter(SLANG_WRITER_CHANNEL_DIAGNOSTIC); }
+ static WriterHelper getError()
+ {
+ return getSingleton()->getWriter(SLANG_WRITER_CHANNEL_STD_ERROR);
+ }
+ static WriterHelper getOut()
+ {
+ return getSingleton()->getWriter(SLANG_WRITER_CHANNEL_STD_OUTPUT);
+ }
+ static WriterHelper getDiagnostic()
+ {
+ return getSingleton()->getWriter(SLANG_WRITER_CHANNEL_DIAGNOSTIC);
+ }
protected:
+ ComPtr<ISlangWriter> m_writers[SLANG_WRITER_CHANNEL_COUNT_OF];
- ComPtr<ISlangWriter> m_writers[SLANG_WRITER_CHANNEL_COUNT_OF];
-
static StdWriters* s_singleton;
};
@@ -52,6 +59,6 @@ inline void StdWriters::flushWriters()
}
}
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-stream.cpp b/source/core/slang-stream.cpp
index 6507c2e56..ca7528f61 100644
--- a/source/core/slang-stream.cpp
+++ b/source/core/slang-stream.cpp
@@ -2,10 +2,11 @@
#ifdef _WIN32
#include <share.h>
#endif
-#include <thread>
#include "slang-io.h"
#include "slang-process.h"
+#include <thread>
+
namespace Slang
{
@@ -20,10 +21,8 @@ SlangResult Stream::readExactly(void* buffer, size_t length)
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FileStream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-FileStream::FileStream() :
- m_handle(nullptr),
- m_fileAccess(FileAccess::None),
- m_endReached(false)
+FileStream::FileStream()
+ : m_handle(nullptr), m_fileAccess(FileAccess::None), m_endReached(false)
{
}
@@ -33,7 +32,11 @@ SlangResult FileStream::init(const String& fileName, FileMode fileMode)
return _init(fileName, fileMode, access, FileShare::None);
}
-SlangResult FileStream::init(const String& fileName, FileMode fileMode, FileAccess access, FileShare share)
+SlangResult FileStream::init(
+ const String& fileName,
+ FileMode fileMode,
+ FileAccess access,
+ FileShare share)
{
return _init(fileName, fileMode, access, share);
}
@@ -120,46 +123,35 @@ SlangResult FileStream::_init(
mode = "ab";
}
break;
- default:
- 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)
+ // 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:
- SLANG_ASSERT(!"Invalid file share mode.");
- return SLANG_FAIL;
+ 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: SLANG_ASSERT(!"Invalid file share mode."); return SLANG_FAIL;
}
if (share == FileShare::None)
-#pragma warning(suppress:4996)
+#pragma warning(suppress : 4996)
m_handle = _wfopen(fileName.toWString(), wideMode);
else
m_handle = _wfsopen(fileName.toWString(), wideMode, shFlag);
@@ -189,7 +181,7 @@ Int64 FileStream::getPosition()
return pos;
#elif defined(__APPLE__)
return ftell(m_handle);
-#else
+#else
fpos64_t pos;
fgetpos64(m_handle, &pos);
return *(Int64*)(&pos);
@@ -201,18 +193,10 @@ SlangResult FileStream::seek(SeekOrigin seekOrigin, Int64 offset)
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:
- SLANG_ASSERT(!"Unsupported seek origin.");
- return SLANG_FAIL;
+ case SeekOrigin::Start: fseekOrigin = SEEK_SET; break;
+ case SeekOrigin::End: fseekOrigin = SEEK_END; break;
+ case SeekOrigin::Current: fseekOrigin = SEEK_CUR; break;
+ default: SLANG_ASSERT(!"Unsupported seek origin."); return SLANG_FAIL;
}
// If endReached is intended to be like feof - then doing a seek will reset it
@@ -301,18 +285,10 @@ SlangResult MemoryStreamBase::seek(SeekOrigin origin, Int64 offset)
Int64 pos = 0;
switch (origin)
{
- case SeekOrigin::Start:
- pos = offset;
- break;
- case SeekOrigin::End:
- pos = Int64(m_contentsSize) + offset;
- break;
- case SeekOrigin::Current:
- pos = Int64(m_position) + offset;
- break;
- default:
- SLANG_ASSERT(!"Unsupported seek origin.");
- return SLANG_E_NOT_IMPLEMENTED;
+ case SeekOrigin::Start: pos = offset; break;
+ case SeekOrigin::End: pos = Int64(m_contentsSize) + offset; break;
+ case SeekOrigin::Current: pos = Int64(m_position) + offset; break;
+ default: SLANG_ASSERT(!"Unsupported seek origin."); return SLANG_E_NOT_IMPLEMENTED;
}
m_atEnd = false;
@@ -338,7 +314,7 @@ SlangResult MemoryStreamBase::read(void* buffer, size_t length, size_t& outReadB
if (maxRead == 0 && length > 0)
{
// At end of stream
- m_atEnd = true;
+ m_atEnd = true;
return SLANG_OK;
}
@@ -353,7 +329,7 @@ SlangResult MemoryStreamBase::read(void* buffer, size_t length, size_t& outReadB
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!! OwnedMemoryStream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-SlangResult OwnedMemoryStream::write(const void * buffer, size_t length)
+SlangResult OwnedMemoryStream::write(const void* buffer, size_t length)
{
if (!canWrite())
{
@@ -406,7 +382,8 @@ SlangResult BufferedReadStream::seek(SeekOrigin origin, Int64 offset)
// So we could seek backwards up to -m_startIndex.
// We don't worry about this here, for simplicity sake.
- if (origin == SeekOrigin::End || origin == SeekOrigin::Start || offset < 0 || offset >= Int64(getCount()))
+ if (origin == SeekOrigin::End || origin == SeekOrigin::Start || offset < 0 ||
+ offset >= Int64(getCount()))
{
// Empty the buffer
_resetBuffer();
@@ -420,8 +397,9 @@ SlangResult BufferedReadStream::seek(SeekOrigin origin, Int64 offset)
}
SlangResult BufferedReadStream::read(void* inBuffer, size_t length, size_t& outReadBytes)
-{
- // If the buffer has no data and the read size is larger than the default read size - may as well just read directly into the output buffer
+{
+ // If the buffer has no data and the read size is larger than the default read size - may as
+ // well just read directly into the output buffer
if (getCount() == 0 && length > m_defaultReadSize)
{
return m_stream->read(inBuffer, length, outReadBytes);
@@ -542,20 +520,21 @@ SlangResult BufferedReadStream::update()
}
else
{
- // Make sure we have the space
+ // Make sure we have the space
const Index prevCount = m_buffer.getCount();
m_buffer.setCount(prevCount + m_defaultReadSize);
m_buffer.setCount(prevCount);
}
}
-
+
{
const Index prevCount = m_buffer.getCount();
m_buffer.setCount(prevCount + m_defaultReadSize);
size_t readBytes = 0;
- const SlangResult res = m_stream->read(m_buffer.getBuffer() + prevCount, m_defaultReadSize, readBytes);
+ const SlangResult res =
+ m_stream->read(m_buffer.getBuffer() + prevCount, m_defaultReadSize, readBytes);
m_buffer.setCount(prevCount + Index(readBytes));
@@ -591,41 +570,37 @@ SlangResult BufferedReadStream::readUntilContains(size_t size)
SlangResult StreamUtil::readAndWrite(
Stream* writeStream,
ArrayView<Byte> bytesToWrite,
- Stream* readStream, List<Byte>& outReadBytes,
+ Stream* readStream,
+ List<Byte>& outReadBytes,
Stream* errStream,
List<Byte>& outErrBytes)
{
- std::thread writeThread([&]()
+ std::thread writeThread(
+ [&]()
{
writeStream->write(bytesToWrite.getBuffer(), (size_t)bytesToWrite.getCount());
writeStream->close();
});
SlangResult readResult = SLANG_OK;
- std::thread readThread([&]()
- {
- readResult = readAll(readStream, 1024, outReadBytes);
- });
- std::thread readErrThread([&]()
- {
- readAll(errStream, 1024, outErrBytes);
- });
+ std::thread readThread([&]() { readResult = readAll(readStream, 1024, outReadBytes); });
+ std::thread readErrThread([&]() { readAll(errStream, 1024, outErrBytes); });
writeThread.join();
readThread.join();
readErrThread.join();
return readResult;
}
-/* static */SlangResult StreamUtil::readAll(Stream* stream, size_t readSize, List<Byte>& ioBytes)
+/* static */ SlangResult StreamUtil::readAll(Stream* stream, size_t readSize, List<Byte>& ioBytes)
{
while (!stream->isEnd())
{
SLANG_RETURN_ON_FAIL(read(stream, readSize, ioBytes));
}
-
+
return SLANG_OK;
}
-/* static */SlangResult StreamUtil::read(Stream* stream, size_t readSize, List<Byte>& ioBytes)
+/* static */ SlangResult StreamUtil::read(Stream* stream, size_t readSize, List<Byte>& ioBytes)
{
readSize = (readSize <= 0) ? 1024 : readSize;
@@ -635,7 +610,8 @@ SlangResult StreamUtil::readAndWrite(
ioBytes.setCount(prevCount + readSize);
size_t readBytesCount;
- SLANG_RETURN_ON_FAIL(stream->read(ioBytes.getBuffer() + prevCount, readSize, readBytesCount));
+ SLANG_RETURN_ON_FAIL(
+ stream->read(ioBytes.getBuffer() + prevCount, readSize, readBytesCount));
ioBytes.setCount(prevCount + Index(readBytesCount));
if (readBytesCount == 0)
@@ -645,7 +621,7 @@ SlangResult StreamUtil::readAndWrite(
}
}
-/* static */SlangResult StreamUtil::discard(Stream* stream)
+/* static */ SlangResult StreamUtil::discard(Stream* stream)
{
Byte buf[1024];
const Index bufSize = SLANG_COUNT_OF(buf);
@@ -654,7 +630,7 @@ SlangResult StreamUtil::readAndWrite(
{
size_t readBytesCount;
SLANG_RETURN_ON_FAIL(stream->read(buf, bufSize, readBytesCount));
-
+
if (readBytesCount == 0)
{
return SLANG_OK;
@@ -662,7 +638,7 @@ SlangResult StreamUtil::readAndWrite(
}
}
-/* static */SlangResult StreamUtil::discardAll(Stream* stream)
+/* static */ SlangResult StreamUtil::discardAll(Stream* stream)
{
while (!stream->isEnd())
{
@@ -672,7 +648,10 @@ SlangResult StreamUtil::readAndWrite(
}
-/* static */SlangResult StreamUtil::readOrDiscard(Stream* stream, size_t readSize, List<Byte>* ioBytes)
+/* static */ SlangResult StreamUtil::readOrDiscard(
+ Stream* stream,
+ size_t readSize,
+ List<Byte>* ioBytes)
{
if (ioBytes)
{
@@ -684,7 +663,10 @@ SlangResult StreamUtil::readAndWrite(
}
}
-/* static */SlangResult StreamUtil::readOrDiscardAll(Stream* stream, size_t readSize, List<Byte>* ioBytes)
+/* static */ SlangResult StreamUtil::readOrDiscardAll(
+ Stream* stream,
+ size_t readSize,
+ List<Byte>* ioBytes)
{
if (ioBytes)
{
@@ -700,10 +682,10 @@ static FILE* _getFileFromStdStreamType(StdStreamType stdStream)
{
switch (stdStream)
{
- case StdStreamType::ErrorOut: return stderr;
- case StdStreamType::Out: return stdout;
- case StdStreamType::In: return stdin;
- default: return nullptr;
+ case StdStreamType::ErrorOut: return stderr;
+ case StdStreamType::Out: return stdout;
+ case StdStreamType::In: return stdin;
+ default: return nullptr;
}
}
@@ -711,14 +693,16 @@ static int _getBufferOptions(StreamBufferStyle style)
{
switch (style)
{
- case StreamBufferStyle::None: return _IONBF;
- case StreamBufferStyle::Line: return _IOLBF;
- default:
- case StreamBufferStyle::Full: return _IOFBF;
+ case StreamBufferStyle::None: return _IONBF;
+ case StreamBufferStyle::Line: return _IOLBF;
+ default:
+ case StreamBufferStyle::Full: return _IOFBF;
}
}
-/* static */SlangResult StreamUtil::setStreamBufferStyle(StdStreamType stdStream, StreamBufferStyle style)
+/* static */ SlangResult StreamUtil::setStreamBufferStyle(
+ StdStreamType stdStream,
+ StreamBufferStyle style)
{
FILE* file = _getFileFromStdStreamType(stdStream);
diff --git a/source/core/slang-stream.h b/source/core/slang-stream.h
index 8459d53d1..78664c17a 100644
--- a/source/core/slang-stream.h
+++ b/source/core/slang-stream.h
@@ -16,61 +16,74 @@ enum class StdStreamType
enum class SeekOrigin
{
- Start, ///< Seek from the start of the stream
- End, ///< Seek from the end of the stream
- Current, ///< Seek from the current cursor position
+ Start, ///< Seek from the start of the stream
+ End, ///< Seek from the end of the stream
+ Current, ///< Seek from the current cursor position
};
class Stream : public RefObject
{
public:
virtual ~Stream() {}
- /// Get the current 'cursor' position in the stream
- virtual Int64 getPosition()=0;
- /// Seek the cursor to a position. How the seek is performed is dependent on the 'origin' and the offset required.
- /// NOTE that *any* seek will reset the 'end of stream' status. See 'read' for requirements for 'isEnd' to be reached.
- virtual SlangResult seek(SeekOrigin origin, Int64 offset)=0;
- /// Read from the current position into buffer.
- /// If there are less bytes available than requested only the amount available will be read. outReadBytes holds the actual amount of bytes read.
- /// It is valid (and not an error) for read to return 0 bytes read - even if the end of the stream.
- ///
- /// 'isEnd' only becomes true when a read is performed *past* the end of a stream.
- /// If a non zero read is performed from the end then isEnd must be true.
- ///
- /// Will return an error if there is a reading failure.
- virtual SlangResult read(void* buffer, size_t length, size_t& outReadBytes) = 0;
- /// Write to the stream from current position
- virtual SlangResult write(const void* buffer, size_t length) = 0;
- /// True if the of the stream has been hit. The 'read' method has more discussion as to when this can occur.
- virtual bool isEnd() = 0;
- /// Returns true if it's possible to read from the stream.
- virtual bool canRead() = 0;
- /// Returns true when it's possible to write to the stream.
- virtual bool canWrite() = 0;
- /// Close the stream. Once closed no more operations can be performed on the stream.
- /// Implies any pending data is flushed.
- virtual void close() = 0;
-
- /// Only applicable for write streams, flushes any buffers to underlying representation (such as pipe, or file)
+ /// Get the current 'cursor' position in the stream
+ virtual Int64 getPosition() = 0;
+ /// Seek the cursor to a position. How the seek is performed is dependent on the 'origin' and
+ /// the offset required. NOTE that *any* seek will reset the 'end of stream' status. See 'read'
+ /// for requirements for 'isEnd' to be reached.
+ virtual SlangResult seek(SeekOrigin origin, Int64 offset) = 0;
+ /// Read from the current position into buffer.
+ /// If there are less bytes available than requested only the amount available will be read.
+ /// outReadBytes holds the actual amount of bytes read. It is valid (and not an error) for read
+ /// to return 0 bytes read - even if the end of the stream.
+ ///
+ /// 'isEnd' only becomes true when a read is performed *past* the end of a stream.
+ /// If a non zero read is performed from the end then isEnd must be true.
+ ///
+ /// Will return an error if there is a reading failure.
+ virtual SlangResult read(void* buffer, size_t length, size_t& outReadBytes) = 0;
+ /// Write to the stream from current position
+ virtual SlangResult write(const void* buffer, size_t length) = 0;
+ /// True if the of the stream has been hit. The 'read' method has more discussion as to when
+ /// this can occur.
+ virtual bool isEnd() = 0;
+ /// Returns true if it's possible to read from the stream.
+ virtual bool canRead() = 0;
+ /// Returns true when it's possible to write to the stream.
+ virtual bool canWrite() = 0;
+ /// Close the stream. Once closed no more operations can be performed on the stream.
+ /// Implies any pending data is flushed.
+ virtual void close() = 0;
+
+ /// Only applicable for write streams, flushes any buffers to underlying representation (such as
+ /// pipe, or file)
virtual SlangResult flush() = 0;
- /// Helper function that will also *fail* if the specified amount of bytes aren't read.
+ /// Helper function that will also *fail* if the specified amount of bytes aren't read.
SlangResult readExactly(void* buffer, size_t length);
};
enum class FileMode
{
- Create, Open, CreateNew, Append
+ Create,
+ Open,
+ CreateNew,
+ Append
};
enum class FileAccess
{
- None = 0, Read = 1, Write = 2, ReadWrite = 3
+ None = 0,
+ Read = 1,
+ Write = 2,
+ ReadWrite = 3
};
enum class FileShare
{
- None, ReadOnly, WriteOnly, ReadWrite
+ None,
+ ReadOnly,
+ WriteOnly,
+ ReadWrite
};
/// Base class for memory streams. Only supports reading and does NOT own contained data.
@@ -81,47 +94,64 @@ public:
virtual Int64 getPosition() SLANG_OVERRIDE { return m_position; }
virtual SlangResult seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE;
- virtual SlangResult read(void * buffer, size_t length, size_t& outReadByts) SLANG_OVERRIDE;
- virtual SlangResult write(const void * buffer, size_t length) SLANG_OVERRIDE { SLANG_UNUSED(buffer); SLANG_UNUSED(length); return SLANG_E_NOT_IMPLEMENTED; }
+ virtual SlangResult read(void* buffer, size_t length, size_t& outReadByts) SLANG_OVERRIDE;
+ virtual SlangResult write(const void* buffer, size_t length) SLANG_OVERRIDE
+ {
+ SLANG_UNUSED(buffer);
+ SLANG_UNUSED(length);
+ return SLANG_E_NOT_IMPLEMENTED;
+ }
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; }
- virtual SlangResult flush() SLANG_OVERRIDE { return canWrite() ? SLANG_OK : SLANG_E_NOT_AVAILABLE; }
+ virtual SlangResult flush() SLANG_OVERRIDE
+ {
+ return canWrite() ? SLANG_OK : SLANG_E_NOT_AVAILABLE;
+ }
- /// Get the contents
- ConstArrayView<uint8_t> getContents() const { return ConstArrayView<uint8_t>(m_contents, m_contentsSize); }
+ /// Get the contents
+ ConstArrayView<uint8_t> getContents() const
+ {
+ return ConstArrayView<uint8_t>(m_contents, m_contentsSize);
+ }
- MemoryStreamBase(FileAccess access = FileAccess::Read, const void* contents = nullptr, size_t contentsSize = 0):
- m_access(access)
+ MemoryStreamBase(
+ FileAccess access = FileAccess::Read,
+ const void* contents = nullptr,
+ size_t contentsSize = 0)
+ : m_access(access)
{
_setContents(contents, contentsSize);
}
protected:
- /// Set to replace wholly current content with specified content
+ /// 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;
+ m_atEnd = false;
}
- /// Update means that the content has changed, but position should be maintained
+ /// 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;
+ 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
+ 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)
+ 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
+ bool
+ m_atEnd; ///< Happens when a read is done and nothing can be returned because already at end
FileAccess m_access;
};
@@ -134,7 +164,7 @@ public:
virtual SlangResult write(const void* buffer, size_t length) SLANG_OVERRIDE;
- /// Set the contents
+ /// Set the contents
void setContent(const void* contents, size_t contentsSize)
{
m_ownedContents.setCount(contentsSize);
@@ -151,12 +181,12 @@ public:
_setContents(m_ownedContents.getBuffer(), m_ownedContents.getCount());
}
- OwnedMemoryStream(FileAccess access) :
- Super(access)
- {}
+ OwnedMemoryStream(FileAccess access)
+ : Super(access)
+ {
+ }
protected:
-
List<uint8_t> m_ownedContents;
};
@@ -166,33 +196,38 @@ public:
typedef Stream Super;
// Stream interface
- virtual Int64 getPosition() SLANG_OVERRIDE;
- virtual SlangResult seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE;
- virtual SlangResult read(void* buffer, size_t length, size_t& outReadBytes) SLANG_OVERRIDE;
- virtual SlangResult write(const void* buffer, size_t length) SLANG_OVERRIDE;
- virtual bool canRead() SLANG_OVERRIDE;
- virtual bool canWrite() SLANG_OVERRIDE;
- virtual void close() SLANG_OVERRIDE;
- virtual bool isEnd() SLANG_OVERRIDE;
+ virtual Int64 getPosition() SLANG_OVERRIDE;
+ virtual SlangResult seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE;
+ virtual SlangResult read(void* buffer, size_t length, size_t& outReadBytes) SLANG_OVERRIDE;
+ virtual SlangResult write(const void* buffer, size_t length) SLANG_OVERRIDE;
+ virtual bool canRead() SLANG_OVERRIDE;
+ virtual bool canWrite() SLANG_OVERRIDE;
+ virtual void close() SLANG_OVERRIDE;
+ virtual bool isEnd() SLANG_OVERRIDE;
virtual SlangResult flush() SLANG_OVERRIDE;
FileStream();
-
+
SlangResult init(const String& fileName, FileMode fileMode, FileAccess access, FileShare share);
SlangResult init(const String& fileName, FileMode fileMode = FileMode::Open);
~FileStream();
private:
- SlangResult _init(const String& fileName, FileMode fileMode, FileAccess access, FileShare share);
+ SlangResult _init(
+ const String& fileName,
+ FileMode fileMode,
+ FileAccess access,
+ FileShare share);
FILE* m_handle;
- FileAccess m_fileAccess;
+ FileAccess m_fileAccess;
bool m_endReached = false;
};
/* A simple BufferedReader. The valid data is between m_startIndex and getCount().
-Can be used as a buffer to build up a result from a stream in memory using 'update' to read to the appropriate buffer size.
+Can be used as a buffer to build up a result from a stream in memory using 'update' to read to the
+appropriate buffer size.
*/
class BufferedReadStream : public Stream
{
@@ -209,10 +244,10 @@ public:
virtual bool isEnd() SLANG_OVERRIDE;
virtual SlangResult flush() SLANG_OVERRIDE;
- /// Will read assuming backing stream is
+ /// Will read assuming backing stream is
SlangResult update();
- /// Consume bytes in the buffer.
+ /// Consume bytes in the buffer.
void consume(Index byteCount);
Byte* getBuffer() { return m_buffer.getBuffer() + m_startIndex; }
@@ -220,31 +255,31 @@ public:
size_t getCount() const { return m_buffer.getCount() - m_startIndex; }
- /// Read until the buffer contains the specified amount of bytes
+ /// Read until the buffer contains the specified amount of bytes
SlangResult readUntilContains(size_t size);
- ConstArrayView<Byte> getView() const { return ConstArrayView<Byte>(getBuffer(), Index(getCount())); }
+ ConstArrayView<Byte> getView() const
+ {
+ return ConstArrayView<Byte>(getBuffer(), Index(getCount()));
+ }
ArrayView<Byte> getView() { return ArrayView<Byte>(getBuffer(), Index(getCount())); }
- BufferedReadStream(Stream* stream) :
- m_stream(stream),
- m_startIndex(0)
+ BufferedReadStream(Stream* stream)
+ : m_stream(stream), m_startIndex(0)
{
-
}
protected:
-
void _resetBuffer()
{
m_startIndex = 0;
m_buffer.setCount(0);
}
- size_t m_defaultReadSize = 1024; ///< When initiating a read the default read size
- List<Byte> m_buffer; ///< Holds the characters
- Index m_startIndex; ///< The start index
- RefPtr<Stream> m_stream; ///< Stream that is being read from
+ size_t m_defaultReadSize = 1024; ///< When initiating a read the default read size
+ List<Byte> m_buffer; ///< Holds the characters
+ Index m_startIndex; ///< The start index
+ RefPtr<Stream> m_stream; ///< Stream that is being read from
};
enum class StreamBufferStyle
@@ -256,14 +291,20 @@ enum class StreamBufferStyle
struct StreamUtil
{
- // Write inputs to writeStream while simultaneously read from readStream and errStream.
- static SlangResult readAndWrite(Stream* writeStream, ArrayView<Byte> bytesToWrite, Stream* readStream, List<Byte>& outReadBytes, Stream* errStream, List<Byte>& outErrBytes);
-
- /// Appends all bytes that can be read from stream into bytes
+ // Write inputs to writeStream while simultaneously read from readStream and errStream.
+ static SlangResult readAndWrite(
+ Stream* writeStream,
+ ArrayView<Byte> bytesToWrite,
+ Stream* readStream,
+ List<Byte>& outReadBytes,
+ Stream* errStream,
+ List<Byte>& outErrBytes);
+
+ /// Appends all bytes that can be read from stream into bytes
static SlangResult readAll(Stream* stream, size_t readSize, List<Byte>& ioBytes);
- /// Read as much as can be read until a 0 sized read, or an error and append onto ioBytes
- /// Read size controls the size of each buffer read. Passing 0, will use the default read size.
+ /// Read as much as can be read until a 0 sized read, or an error and append onto ioBytes
+ /// Read size controls the size of each buffer read. Passing 0, will use the default read size.
static SlangResult read(Stream* stream, size_t readSize, List<Byte>& ioBytes);
static SlangResult discard(Stream* stream);
diff --git a/source/core/slang-string-escape-util.cpp b/source/core/slang-string-escape-util.cpp
index 77399552e..a6a70ce76 100644
--- a/source/core/slang-string-escape-util.cpp
+++ b/source/core/slang-string-escape-util.cpp
@@ -1,12 +1,12 @@
#include "slang-string-escape-util.h"
#include "slang-char-util.h"
-#include "slang-text-io.h"
-#include "slang-memory-arena.h"
-
#include "slang-com-helper.h"
+#include "slang-memory-arena.h"
+#include "slang-text-io.h"
-namespace Slang {
+namespace Slang
+{
// !!!!!!!!!!!!!!!!!!!!!!!!!! SpaceStringEscapeHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -15,16 +15,24 @@ class SpaceStringEscapeHandler : public StringEscapeHandler
public:
typedef StringEscapeHandler Super;
- virtual bool isQuotingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE { return isEscapingNeeded(slice); }
-
+ virtual bool isQuotingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE
+ {
+ return isEscapingNeeded(slice);
+ }
+
virtual bool isEscapingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
virtual bool isUnescapingNeeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
- virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
- virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
+ virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out)
+ SLANG_OVERRIDE;
+ virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out)
+ SLANG_OVERRIDE;
virtual SlangResult lexQuoted(const char* cursor, const char** outCursor) SLANG_OVERRIDE;
- SpaceStringEscapeHandler() : Super('"') {}
+ SpaceStringEscapeHandler()
+ : Super('"')
+ {
+ }
};
bool SpaceStringEscapeHandler::isEscapingNeeded(const UnownedStringSlice& slice)
@@ -39,7 +47,9 @@ bool SpaceStringEscapeHandler::isUnescapingNeeeded(const UnownedStringSlice& sli
return false;
}
-SlangResult SpaceStringEscapeHandler::appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out)
+SlangResult SpaceStringEscapeHandler::appendUnescaped(
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
if (slice.indexOf('"') >= 0)
{
@@ -50,7 +60,9 @@ SlangResult SpaceStringEscapeHandler::appendUnescaped(const UnownedStringSlice&
return SLANG_OK;
}
-SlangResult SpaceStringEscapeHandler::appendEscaped(const UnownedStringSlice& slice, StringBuilder& out)
+SlangResult SpaceStringEscapeHandler::appendEscaped(
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
if (slice.indexOf('"') >= 0)
{
@@ -60,7 +72,9 @@ SlangResult SpaceStringEscapeHandler::appendEscaped(const UnownedStringSlice& sl
return SLANG_OK;
}
-/* static */SlangResult SpaceStringEscapeHandler::lexQuoted(const char* cursor, const char** outCursor)
+/* static */ SlangResult SpaceStringEscapeHandler::lexQuoted(
+ const char* cursor,
+ const char** outCursor)
{
*outCursor = cursor;
@@ -80,14 +94,14 @@ SlangResult SpaceStringEscapeHandler::appendEscaped(const UnownedStringSlice& sl
}
switch (c)
{
- case 0:
- case '\n':
- case '\r':
+ case 0:
+ case '\n':
+ case '\r':
{
// Didn't hit closing quote!
return SLANG_FAIL;
}
- default:
+ default:
{
++cursor;
break;
@@ -97,7 +111,6 @@ SlangResult SpaceStringEscapeHandler::appendEscaped(const UnownedStringSlice& sl
}
-
// !!!!!!!!!!!!!!!!!!!!!!!!!! CppStringEscapeHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
class CppStringEscapeHandler : public StringEscapeHandler
@@ -105,31 +118,40 @@ class CppStringEscapeHandler : public StringEscapeHandler
public:
typedef StringEscapeHandler Super;
- virtual bool isQuotingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE { SLANG_UNUSED(slice); return true; }
+ virtual bool isQuotingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE
+ {
+ SLANG_UNUSED(slice);
+ return true;
+ }
virtual bool isEscapingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
virtual bool isUnescapingNeeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
- virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
- virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
+ virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out)
+ SLANG_OVERRIDE;
+ virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out)
+ SLANG_OVERRIDE;
virtual SlangResult lexQuoted(const char* cursor, const char** outCursor) SLANG_OVERRIDE;
- CppStringEscapeHandler() : Super('"') {}
+ CppStringEscapeHandler()
+ : Super('"')
+ {
+ }
};
static char _getCppEscapedChar(char c)
{
switch (c)
{
- case '\b': return 'b';
- case '\f': return 'f';
- case '\n': return 'n';
- case '\r': return 'r';
- case '\a': return 'a';
- case '\t': return 't';
- case '\v': return 'v';
- case '\'': return '\'';
- case '\"': return '"';
- case '\\': return '\\';
- default: return 0;
+ case '\b': return 'b';
+ case '\f': return 'f';
+ case '\n': return 'n';
+ case '\r': return 'r';
+ case '\a': return 'a';
+ case '\t': return 't';
+ case '\v': return 'v';
+ case '\'': return '\'';
+ case '\"': return '"';
+ case '\\': return '\\';
+ default: return 0;
}
}
@@ -137,17 +159,17 @@ static char _getCppUnescapedChar(char c)
{
switch (c)
{
- case 'b': return '\b';
- case 'f': return '\f';
- case 'n': return '\n';
- case 'r': return '\r';
- case 'a': return '\a';
- case 't': return '\t';
- case 'v': return '\v';
- case '\'': return '\'';
- case '\"': return '"';
- case '\\': return '\\';
- default: return 0;
+ case 'b': return '\b';
+ case 'f': return '\f';
+ case 'n': return '\n';
+ case 'r': return '\r';
+ case 'a': return '\a';
+ case 't': return '\t';
+ case 'v': return '\v';
+ case '\'': return '\'';
+ case '\"': return '"';
+ case '\\': return '\\';
+ default: return 0;
}
}
@@ -156,10 +178,10 @@ bool CppStringEscapeHandler::isUnescapingNeeeded(const UnownedStringSlice& slice
return slice.indexOf('\\') >= 0;
}
-/* static */bool CppStringEscapeHandler::isEscapingNeeded(const UnownedStringSlice& slice)
+/* static */ bool CppStringEscapeHandler::isEscapingNeeded(const UnownedStringSlice& slice)
{
const char* cur = slice.begin();
- const char*const end = slice.end();
+ const char* const end = slice.end();
for (; cur < end; ++cur)
{
@@ -167,14 +189,14 @@ bool CppStringEscapeHandler::isUnescapingNeeeded(const UnownedStringSlice& slice
switch (c)
{
- case '\'':
- case '\"':
- case '\\':
+ case '\'':
+ case '\"':
+ case '\\':
{
- // Strictly speaking ' shouldn't need a quote if in a C style string.
+ // Strictly speaking ' shouldn't need a quote if in a C style string.
return true;
}
- default:
+ default:
{
if (c < ' ' || c >= 0x7e)
{
@@ -187,11 +209,13 @@ bool CppStringEscapeHandler::isUnescapingNeeeded(const UnownedStringSlice& slice
return false;
}
-SlangResult CppStringEscapeHandler::appendEscaped(const UnownedStringSlice& slice, StringBuilder& out)
+SlangResult CppStringEscapeHandler::appendEscaped(
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
const char* start = slice.begin();
const char* cur = start;
- const char*const end = slice.end();
+ const char* const end = slice.end();
// TODO(JS): A cleverer implementation might support U and u prefixing for unicode characters.
// For now we just stick with hex if it's not 'regular' ascii.
@@ -222,12 +246,12 @@ SlangResult CppStringEscapeHandler::appendEscaped(const UnownedStringSlice& slic
out.append(start, cur);
}
- // NOTE! There is a possible flaw around checking 'next' character (used for outputting oct and hex)
- // If a string is constructed appended in parts, the next character is not available so the problem below can still
- // occur.
+ // NOTE! There is a possible flaw around checking 'next' character (used for outputting
+ // oct and hex) If a string is constructed appended in parts, the next character is not
+ // available so the problem below can still occur.
- // Another solution to this problem would be to output "", but that makes some other assumptions
- // For example Slang doesn't support that style.
+ // Another solution to this problem would be to output "", but that makes some other
+ // assumptions For example Slang doesn't support that style.
// C++ greedily consumes hex/octal digits. This is a problem if we have bytes
// 0, '1' as by default this will output as
@@ -240,10 +264,12 @@ SlangResult CppStringEscapeHandler::appendEscaped(const UnownedStringSlice& slic
// On testing in Visual Studio hex can indeed be more than 3 digits
- // There is a problem outputting values in hex, because C++ allows *any* amount of hex digits.
- // We could work around with \u \U but they are later extensions (C++11) and have other issue
+ // There is a problem outputting values in hex, because C++ allows *any* amount of hex
+ // digits. We could work around with \u \U but they are later extensions (C++11) and
+ // have other issue
- // The solution taken here is to always output as octal, because octal can be at most 3 digits.
+ // The solution taken here is to always output as octal, because octal can be at most 3
+ // digits.
// Special case handling of 0
if (c == 0 && !(cur + 1 < end && CharUtil::isOctalDigit(cur[1])))
@@ -253,8 +279,9 @@ SlangResult CppStringEscapeHandler::appendEscaped(const UnownedStringSlice& slic
}
else
{
- // A slightly more sophisticated implementation could output less digits if needed, if not followed by an octal
- // digit, but for now we go simple and output all 3 digits
+ // A slightly more sophisticated implementation could output less digits if needed,
+ // if not followed by an octal digit, but for now we go simple and output all 3
+ // digits
const uint32_t v = uint32_t(c);
@@ -279,11 +306,13 @@ SlangResult CppStringEscapeHandler::appendEscaped(const UnownedStringSlice& slic
return SLANG_OK;
}
-SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out)
+SlangResult CppStringEscapeHandler::appendUnescaped(
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
const char* start = slice.begin();
const char* cur = start;
- const char*const end = slice.end();
+ const char* const end = slice.end();
while (cur < end)
{
@@ -297,7 +326,7 @@ SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& sl
out.append(start, cur);
}
- /// Next
+ /// Next
cur++;
if (cur >= end)
@@ -311,17 +340,17 @@ SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& sl
// Need to handle various escape sequence cases
switch (nextC)
{
- case '\'':
- case '\"':
- case '\\':
- case '?':
- case 'a':
- case 'b':
- case 'f':
- case 'n':
- case 'r':
- case 't':
- case 'v':
+ case '\'':
+ case '\"':
+ case '\\':
+ case '?':
+ case 'a':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'v':
{
const char unescapedChar = _getCppUnescapedChar(nextC);
if (unescapedChar == 0)
@@ -334,13 +363,20 @@ SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& sl
start = cur;
break;
}
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
{
// Rewind back a character, as first digit is the 'nextC'
--cur;
- // Don't need to check for enough characters, because there must be 1 - the nextC
+ // Don't need to check for enough characters, because there must be 1 - the
+ // nextC
// octal escape: up to 3 characters
int value = 0;
@@ -355,7 +391,7 @@ SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& sl
{
break;
}
- value = (value << 3) | digitValue;
+ value = (value << 3) | digitValue;
}
out.appendChar(char(value));
@@ -363,7 +399,7 @@ SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& sl
start = cur;
break;
}
- case 'x':
+ case 'x':
{
/// In the C++ standard we consume hex digits until we hit a non hex digit
uint32_t value = 0;
@@ -385,8 +421,8 @@ SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& sl
}
else
{
- // It's arguable what is appropriate. We only decode/encode 4, which the current spec has,
- // but 6 are possible, so lets go large.
+ // It's arguable what is appropriate. We only decode/encode 4, which the
+ // current spec has, but 6 are possible, so lets go large.
const Index maxUtf8EncodeCount = 6;
char* chars = out.prepareForAppend(maxUtf8EncodeCount);
@@ -398,8 +434,8 @@ SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& sl
start = cur;
break;
}
- case 'u':
- case 'U':
+ case 'u':
+ case 'U':
{
// u implies 4 hex digits
// U implies 6.
@@ -433,8 +469,8 @@ SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& sl
}
else
{
- // It's arguable what is appropriate. We only decode/encode 4, which the current spec has,
- // but 6 are possible, so lets go large.
+ // It's arguable what is appropriate. We only decode/encode 4, which the
+ // current spec has, but 6 are possible, so lets go large.
const Index maxUtf8EncodeCount = 6;
char* chars = out.prepareForAppend(maxUtf8EncodeCount);
@@ -446,7 +482,7 @@ SlangResult CppStringEscapeHandler::appendUnescaped(const UnownedStringSlice& sl
start = cur;
break;
}
- default:
+ default:
{
return SLANG_FAIL;
}
@@ -487,36 +523,42 @@ SlangResult CppStringEscapeHandler::lexQuoted(const char* cursor, const char** o
}
switch (c)
{
- case 0:
- case '\n':
- case '\r':
+ case 0:
+ case '\n':
+ case '\r':
{
// Didn't hit closing quote!
return SLANG_FAIL;
}
- case '\\':
+ case '\\':
{
++cursor;
// Need to handle various escape sequence cases
switch (*cursor)
{
- case '\'':
- case '\"':
- case '\\':
- case '?':
- case 'a':
- case 'b':
- case 'f':
- case 'n':
- case 'r':
- case 't':
- case 'v':
+ case '\'':
+ case '\"':
+ case '\\':
+ case '?':
+ case 'a':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'v':
{
++cursor;
break;
}
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
{
// octal escape: up to 3 characters
++cursor;
@@ -535,11 +577,12 @@ SlangResult CppStringEscapeHandler::lexQuoted(const char* cursor, const char** o
}
break;
}
- case 'x':
+ case 'x':
{
// hexadecimal escape: any number of characters
++cursor;
- for (; CharUtil::isHexDigit(*cursor); ++cursor);
+ for (; CharUtil::isHexDigit(*cursor); ++cursor)
+ ;
// TODO: Unicode escape sequences
break;
@@ -547,7 +590,7 @@ SlangResult CppStringEscapeHandler::lexQuoted(const char* cursor, const char** o
}
break;
}
- default:
+ default:
{
++cursor;
break;
@@ -563,14 +606,23 @@ class JSONStringEscapeHandler : public StringEscapeHandler
public:
typedef StringEscapeHandler Super;
- virtual bool isQuotingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE { SLANG_UNUSED(slice); return true; }
+ virtual bool isQuotingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE
+ {
+ SLANG_UNUSED(slice);
+ return true;
+ }
virtual bool isEscapingNeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
virtual bool isUnescapingNeeeded(const UnownedStringSlice& slice) SLANG_OVERRIDE;
- virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
- virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out) SLANG_OVERRIDE;
+ virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out)
+ SLANG_OVERRIDE;
+ virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out)
+ SLANG_OVERRIDE;
virtual SlangResult lexQuoted(const char* cursor, const char** outCursor) SLANG_OVERRIDE;
- JSONStringEscapeHandler() : Super('"') {}
+ JSONStringEscapeHandler()
+ : Super('"')
+ {
+ }
};
bool JSONStringEscapeHandler::isUnescapingNeeeded(const UnownedStringSlice& slice)
@@ -581,7 +633,7 @@ bool JSONStringEscapeHandler::isUnescapingNeeeded(const UnownedStringSlice& slic
bool JSONStringEscapeHandler::isEscapingNeeded(const UnownedStringSlice& slice)
{
const char* cur = slice.begin();
- const char*const end = slice.end();
+ const char* const end = slice.end();
for (; cur < end; ++cur)
{
@@ -589,13 +641,13 @@ bool JSONStringEscapeHandler::isEscapingNeeded(const UnownedStringSlice& slice)
switch (c)
{
- case '\"':
- case '\\':
- case '/':
+ case '\"':
+ case '\\':
+ case '/':
{
return true;
}
- default:
+ default:
{
if (c < ' ' || c >= 0x7e)
{
@@ -617,30 +669,30 @@ SlangResult JSONStringEscapeHandler::lexQuoted(const char* cursor, const char**
switch (c)
{
- case 0: return SLANG_FAIL;
- case '"':
+ case 0: return SLANG_FAIL;
+ case '"':
{
*outCursor = cursor;
return SLANG_OK;
}
- case '\\':
+ case '\\':
{
const char nextC = *cursor;
switch (nextC)
{
- case '"':
- case '\\':
- case '/':
- case 'b':
- case 'f':
- case 'n':
- case 'r':
- case 't':
+ case '"':
+ case '\\':
+ case '/':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
{
++cursor;
break;
}
- case 'u':
+ case 'u':
{
cursor++;
for (Index i = 0; i < 4; ++i)
@@ -655,8 +707,8 @@ SlangResult JSONStringEscapeHandler::lexQuoted(const char* cursor, const char**
}
}
}
- // Somewhat surprisingly it appears it's valid to have \r\n inside of quotes.
- default: break;
+ // Somewhat surprisingly it appears it's valid to have \r\n inside of quotes.
+ default: break;
}
}
}
@@ -665,15 +717,15 @@ static char _getJSONEscapedChar(char c)
{
switch (c)
{
- case '\b': return 'b';
- case '\f': return 'f';
- case '\n': return 'n';
- case '\r': return 'r';
- case '\t': return 't';
- case '\\': return '\\';
- case '/': return '/';
- case '"': return '"';
- default: return 0;
+ case '\b': return 'b';
+ case '\f': return 'f';
+ case '\n': return 'n';
+ case '\r': return 'r';
+ case '\t': return 't';
+ case '\\': return '\\';
+ case '/': return '/';
+ case '"': return '"';
+ default: return 0;
}
}
@@ -681,15 +733,15 @@ static char _getJSONUnescapedChar(char c)
{
switch (c)
{
- case 'b': return '\b';
- case 'f': return '\f';
- case 'n': return '\n';
- case 'r': return '\r';
- case 't': return '\t';
- case '\\': return '\\';
- case '/': return '/';
- case '"': return '"';
- default: return 0;
+ case 'b': return '\b';
+ case 'f': return '\f';
+ case 'n': return '\n';
+ case 'r': return '\r';
+ case 't': return '\t';
+ case '\\': return '\\';
+ case '/': return '/';
+ case '"': return '"';
+ default: return 0;
}
}
@@ -745,16 +797,18 @@ static void _appendHex16(uint32_t value, StringBuilder& out)
out.append(UnownedStringSlice(buf, 6));
}
-SlangResult JSONStringEscapeHandler::appendEscaped(const UnownedStringSlice& slice, StringBuilder& out)
+SlangResult JSONStringEscapeHandler::appendEscaped(
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
const char* start = slice.begin();
const char* cur = start;
- const char*const end = slice.end();
+ const char* const end = slice.end();
for (; cur < end; ++cur)
{
const char c = *cur;
-
+
const char escapedChar = _getJSONEscapedChar(c);
if (escapedChar)
@@ -814,11 +868,13 @@ SlangResult JSONStringEscapeHandler::appendEscaped(const UnownedStringSlice& sli
return SLANG_OK;
}
-SlangResult JSONStringEscapeHandler::appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out)
+SlangResult JSONStringEscapeHandler::appendUnescaped(
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
const char* start = slice.begin();
const char* cur = start;
- const char*const end = slice.end();
+ const char* const end = slice.end();
for (; cur < end; ++cur)
{
@@ -832,7 +888,7 @@ SlangResult JSONStringEscapeHandler::appendUnescaped(const UnownedStringSlice& s
out.append(start, cur);
}
- /// Next
+ /// Next
cur++;
if (cur >= end)
@@ -843,14 +899,14 @@ SlangResult JSONStringEscapeHandler::appendUnescaped(const UnownedStringSlice& s
// Need to handle various escape sequence cases
switch (*cur)
{
- case '\"':
- case '\\':
- case '/':
- case 'b':
- case 'f':
- case 'n':
- case 'r':
- case 't':
+ case '\"':
+ case '\\':
+ case '/':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
{
const char unescapedChar = _getJSONUnescapedChar(*cur);
if (unescapedChar == 0)
@@ -863,7 +919,7 @@ SlangResult JSONStringEscapeHandler::appendUnescaped(const UnownedStringSlice& s
start = cur + 1;
break;
}
- case 'u':
+ case 'u':
{
uint32_t value = 0;
cur++;
@@ -884,9 +940,9 @@ SlangResult JSONStringEscapeHandler::appendUnescaped(const UnownedStringSlice& s
}
else if (digitC >= 'a' && digitC <= 'f')
{
- digitValue = digitC -'a' + 10;
+ digitValue = digitC - 'a' + 10;
}
- else if(digitC >= 'A' && digitC <= 'F')
+ else if (digitC >= 'A' && digitC <= 'F')
{
digitValue = digitC - 'A' + 10;
}
@@ -899,9 +955,9 @@ SlangResult JSONStringEscapeHandler::appendUnescaped(const UnownedStringSlice& s
}
cur += 4;
- // NOTE! Strictly speaking we may want to combine 2 UTF16 surrogates to make a single
- // UTF8 encoded char.
-
+ // NOTE! Strictly speaking we may want to combine 2 UTF16 surrogates to make a
+ // single UTF8 encoded char.
+
// Need to encode in UTF8 to concat
char buf[8];
@@ -913,7 +969,7 @@ SlangResult JSONStringEscapeHandler::appendUnescaped(const UnownedStringSlice& s
cur--;
break;
}
- default:
+ default:
{
// Can't decode
return SLANG_FAIL;
@@ -941,17 +997,21 @@ StringEscapeUtil::Handler* StringEscapeUtil::getHandler(Style style)
{
switch (style)
{
- case Style::Cpp: return &g_cppHandler;
- case Style::Space: return &g_spaceHandler;
- case Style::JSON: return &g_jsonHandler;
- // TODO(JS): For now we make Slang language string encoding/decoding the same as C++
- // That may not be desirable because C++ has a variety of surprising edge cases (for example around \x)
- case Style::Slang: return &g_cppHandler;
- default: return nullptr;
+ case Style::Cpp: return &g_cppHandler;
+ case Style::Space: return &g_spaceHandler;
+ case Style::JSON: return &g_jsonHandler;
+ // TODO(JS): For now we make Slang language string encoding/decoding the same as C++
+ // That may not be desirable because C++ has a variety of surprising edge cases (for example
+ // around \x)
+ case Style::Slang: return &g_cppHandler;
+ default: return nullptr;
}
}
-/* static */SlangResult StringEscapeUtil::appendQuoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out)
+/* static */ SlangResult StringEscapeUtil::appendQuoted(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
const char quoteChar = handler->getQuoteChar();
out.appendChar(quoteChar);
@@ -960,7 +1020,10 @@ StringEscapeUtil::Handler* StringEscapeUtil::getHandler(Style style)
return res;
}
-/* static */SlangResult StringEscapeUtil::appendUnquoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out)
+/* static */ SlangResult StringEscapeUtil::appendUnquoted(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
const Index len = slice.getLength();
@@ -973,7 +1036,10 @@ StringEscapeUtil::Handler* StringEscapeUtil::getHandler(Style style)
return handler->appendUnescaped(slice.subString(1, len - 2), out);
}
-/* static */SlangResult StringEscapeUtil::appendMaybeQuoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out)
+/* static */ SlangResult StringEscapeUtil::appendMaybeQuoted(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
if (handler->isQuotingNeeded(slice))
{
@@ -986,13 +1052,15 @@ StringEscapeUtil::Handler* StringEscapeUtil::getHandler(Style style)
}
}
-/* static */bool StringEscapeUtil::isQuoted(char quoteChar, UnownedStringSlice& slice)
+/* static */ bool StringEscapeUtil::isQuoted(char quoteChar, UnownedStringSlice& slice)
{
const Index len = slice.getLength();
return len >= 2 && slice[0] == quoteChar && slice[len - 1] == quoteChar;
}
-/* static */UnownedStringSlice StringEscapeUtil::unquote(char quoteChar, const UnownedStringSlice& slice)
+/* static */ UnownedStringSlice StringEscapeUtil::unquote(
+ char quoteChar,
+ const UnownedStringSlice& slice)
{
const Index len = slice.getLength();
if (len >= 2 && slice[0] == quoteChar && slice[len - 1] == quoteChar)
@@ -1003,7 +1071,10 @@ StringEscapeUtil::Handler* StringEscapeUtil::getHandler(Style style)
return UnownedStringSlice();
}
-/* static */SlangResult StringEscapeUtil::appendMaybeUnquoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out)
+/* static */ SlangResult StringEscapeUtil::appendMaybeUnquoted(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
const char quoteChar = handler->getQuoteChar();
@@ -1020,12 +1091,17 @@ StringEscapeUtil::Handler* StringEscapeUtil::getHandler(Style style)
}
}
-/* static */SlangResult StringEscapeUtil::isUnescapeShellLikeNeeded(Handler* handler, const UnownedStringSlice& slice)
+/* static */ SlangResult StringEscapeUtil::isUnescapeShellLikeNeeded(
+ Handler* handler,
+ const UnownedStringSlice& slice)
{
return slice.indexOf(handler->getQuoteChar()) >= 0;
}
-/* static */SlangResult StringEscapeUtil::unescapeShellLike(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out)
+/* static */ SlangResult StringEscapeUtil::unescapeShellLike(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out)
{
StringBuilder buf;
const char quoteChar = handler->getQuoteChar();
@@ -1051,7 +1127,8 @@ StringEscapeUtil::Handler* StringEscapeUtil::getHandler(Style style)
SLANG_RETURN_ON_FAIL(handler->lexQuoted(remaining.begin() + index, &quotedEnd));
// Unescape it
- SLANG_RETURN_ON_FAIL(appendUnquoted(handler, UnownedStringSlice(remaining.begin() + index, quotedEnd), out));
+ SLANG_RETURN_ON_FAIL(
+ appendUnquoted(handler, UnownedStringSlice(remaining.begin() + index, quotedEnd), out));
// Fix up remaining
remaining = UnownedStringSlice(quotedEnd, remaining.end());
diff --git a/source/core/slang-string-escape-util.h b/source/core/slang-string-escape-util.h
index c3a43b623..6e02d772d 100644
--- a/source/core/slang-string-escape-util.h
+++ b/source/core/slang-string-escape-util.h
@@ -1,39 +1,41 @@
#ifndef SLANG_CORE_STRING_ESCAPE_UTIL_H
#define SLANG_CORE_STRING_ESCAPE_UTIL_H
-#include "slang-string.h"
#include "slang-list.h"
+#include "slang-string.h"
-namespace Slang {
+namespace Slang
+{
class StringEscapeHandler
{
public:
-
- /// True if quoting is needed
+ /// True if quoting is needed
virtual bool isQuotingNeeded(const UnownedStringSlice& slice) = 0;
- /// True if any escaping is needed. If not slice can be used (assuming appropriate quoting) as is
+ /// True if any escaping is needed. If not slice can be used (assuming appropriate quoting) as
+ /// is
virtual bool isEscapingNeeded(const UnownedStringSlice& slice) = 0;
- /// True if we need to unescape
+ /// True if we need to unescape
virtual bool isUnescapingNeeeded(const UnownedStringSlice& slice) = 0;
- /// Takes slice and adds any appropriate escaping (for example C++/C type escaping for special characters like '\', '"' and if not ascii will write out as hex sequence)
- /// Does not append quotes
+ /// Takes slice and adds any appropriate escaping (for example C++/C type escaping for special
+ /// characters like '\', '"' and if not ascii will write out as hex sequence) Does not append
+ /// quotes
virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out) = 0;
- /// Given a slice append it unescaped
- /// Does not consume surrounding quotes
+ /// Given a slice append it unescaped
+ /// Does not consume surrounding quotes
virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out) = 0;
- /// Lex quoted text.
- /// The first character of cursor should be the quoteCharacter.
- /// cursor points to the string to be lexed - must typically be 0 terminated.
- /// outCursor on successful lex will be at the next character after was processed.
+ /// Lex quoted text.
+ /// The first character of cursor should be the quoteCharacter.
+ /// cursor points to the string to be lexed - must typically be 0 terminated.
+ /// outCursor on successful lex will be at the next character after was processed.
virtual SlangResult lexQuoted(const char* cursor, const char** outCursor) = 0;
SLANG_FORCE_INLINE char getQuoteChar() const { return m_quoteChar; }
- StringEscapeHandler(char quoteChar):
- m_quoteChar(quoteChar)
+ StringEscapeHandler(char quoteChar)
+ : m_quoteChar(quoteChar)
{
}
@@ -43,8 +45,8 @@ protected:
/* A set of function that can be used for escaping/unescaping quoting/unquoting strings.
-The distinction between 'escaping' and 'quoting' here, is just that escaping is the 'payload' of quotes.
-In *principal* the Style can determine different styles of escaping that can be used.
+The distinction between 'escaping' and 'quoting' here, is just that escaping is the 'payload' of
+quotes. In *principal* the Style can determine different styles of escaping that can be used.
*/
struct StringEscapeUtil
{
@@ -52,43 +54,65 @@ struct StringEscapeUtil
enum class Style
{
- Cpp, ///< Cpp style quoting and escape handling
- Space, ///< Applies quotes if there are spaces. Does not escape.
- JSON, ///< Json encoding
- Slang, ///< Slang style string encoding (For now same as Cpp but that may change in the future)
+ Cpp, ///< Cpp style quoting and escape handling
+ Space, ///< Applies quotes if there are spaces. Does not escape.
+ JSON, ///< Json encoding
+ Slang, ///< Slang style string encoding (For now same as Cpp but that may change in the
+ ///< future)
CountOf,
};
- /// Given a style returns a handler
+ /// Given a style returns a handler
static Handler* getHandler(Style style);
- /// Get without quotes. Will assert if not correctly quoted
+ /// Get without quotes. Will assert if not correctly quoted
static UnownedStringSlice unquote(char quoteChar, const UnownedStringSlice& slice);
- static UnownedStringSlice unquote(Handler* handler, const UnownedStringSlice& slice) { return unquote(handler->getQuoteChar(), slice); }
+ static UnownedStringSlice unquote(Handler* handler, const UnownedStringSlice& slice)
+ {
+ return unquote(handler->getQuoteChar(), slice);
+ }
/// True is slice is quoted
static bool isQuoted(char quoteChar, UnownedStringSlice& slice);
- static bool isQuoted(Handler* handler, UnownedStringSlice& slice) { return isQuoted(handler->getQuoteChar(), slice); }
-
- /// If quoting is needed appends to out quoted
- static SlangResult appendMaybeQuoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out);
-
- /// If the slice appears to be quoted for the style, unquote it, else just append to out
- static SlangResult appendMaybeUnquoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out);
-
- /// Appends to out slice without quotes
- static SlangResult appendUnquoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out);
-
- /// Append with quotes (even if not needed)
- static SlangResult appendQuoted(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out);
-
+ static bool isQuoted(Handler* handler, UnownedStringSlice& slice)
+ {
+ return isQuoted(handler->getQuoteChar(), slice);
+ }
- /// True if requires 'shell-like' unescape. With shell-like, quoting does *not* have to start at the start of the slice.
- /// and there may be multiple quoted section
+ /// If quoting is needed appends to out quoted
+ static SlangResult appendMaybeQuoted(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out);
+
+ /// If the slice appears to be quoted for the style, unquote it, else just append to out
+ static SlangResult appendMaybeUnquoted(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out);
+
+ /// Appends to out slice without quotes
+ static SlangResult appendUnquoted(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out);
+
+ /// Append with quotes (even if not needed)
+ static SlangResult appendQuoted(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out);
+
+
+ /// True if requires 'shell-like' unescape. With shell-like, quoting does *not* have to start at
+ /// the start of the slice. and there may be multiple quoted section
static SlangResult isUnescapeShellLikeNeeded(Handler* handler, const UnownedStringSlice& slice);
- /// Shells can have multiple quoted sections. This function makes a string with out quoting
- static SlangResult unescapeShellLike(Handler* handler, const UnownedStringSlice& slice, StringBuilder& out);
+ /// Shells can have multiple quoted sections. This function makes a string with out quoting
+ static SlangResult unescapeShellLike(
+ Handler* handler,
+ const UnownedStringSlice& slice,
+ StringBuilder& out);
};
diff --git a/source/core/slang-string-slice-index-map.cpp b/source/core/slang-string-slice-index-map.cpp
index d147556e4..dded10537 100644
--- a/source/core/slang-string-slice-index-map.cpp
+++ b/source/core/slang-string-slice-index-map.cpp
@@ -5,7 +5,9 @@ namespace Slang
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringSliceIndexMap !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-StringSliceIndexMap::CountIndex StringSliceIndexMap::add(const UnownedStringSlice& key, Index valueIndex)
+StringSliceIndexMap::CountIndex StringSliceIndexMap::add(
+ const UnownedStringSlice& key,
+ Index valueIndex)
{
StringSlicePool::Handle handle;
m_pool.findOrAdd(key, handle);
@@ -22,7 +24,9 @@ StringSliceIndexMap::CountIndex StringSliceIndexMap::add(const UnownedStringSlic
return countIndex;
}
-StringSliceIndexMap::CountIndex StringSliceIndexMap::findOrAdd(const UnownedStringSlice& key, Index defaultValueIndex)
+StringSliceIndexMap::CountIndex StringSliceIndexMap::findOrAdd(
+ const UnownedStringSlice& key,
+ Index defaultValueIndex)
{
StringSlicePool::Handle handle;
m_pool.findOrAdd(key, handle);
diff --git a/source/core/slang-string-slice-index-map.h b/source/core/slang-string-slice-index-map.h
index c57e0f570..b7c316c24 100644
--- a/source/core/slang-string-slice-index-map.h
+++ b/source/core/slang-string-slice-index-map.h
@@ -2,59 +2,61 @@
#define SLANG_CORE_STRING_SLICE_INDEX_MAP_H
#include "slang-basic.h"
-
#include "slang-string-slice-pool.h"
namespace Slang
{
-/* Maps an UnownedStringSlice to an index. All substrings are held internally in a StringSlicePool, and so
-owned by the type.
+/* Maps an UnownedStringSlice to an index. All substrings are held internally in a StringSlicePool,
+and so owned by the type.
*/
class StringSliceIndexMap
{
public:
- /// An index that identifies a key value pair.
+ /// An index that identifies a key value pair.
typedef Index CountIndex;
- /// Adds a key, value pair. Returns the CountIndex of the pair.
- /// If there is already a value stored for the key it is replaced.
+ /// Adds a key, value pair. Returns the CountIndex of the pair.
+ /// If there is already a value stored for the key it is replaced.
CountIndex add(const UnownedStringSlice& key, Index valueIndex);
- /// Finds or adds the slice. If the slice is added the defaultValueIndex is set.
- /// If not the index associated with the slice remains the same.
- /// Returns the CountIndex where the key,value pair are stored
+ /// Finds or adds the slice. If the slice is added the defaultValueIndex is set.
+ /// If not the index associated with the slice remains the same.
+ /// Returns the CountIndex where the key,value pair are stored
CountIndex findOrAdd(const UnownedStringSlice& key, Index defaultValueIndex);
- /// Gets the index associated with the key. Returns -1 if there is no associated index.
+ /// Gets the index associated with the key. Returns -1 if there is no associated index.
SLANG_FORCE_INLINE Index getValue(const UnownedStringSlice& key);
- /// Get the amount of pairs in the map
+ /// Get the amount of pairs in the map
Index getCount() const { return m_indexMap.getCount(); }
- /// Get the slice and the index at the specified index
+ /// Get the slice and the index at the specified index
SLANG_INLINE KeyValuePair<UnownedStringSlice, Index> getAt(CountIndex countIndex) const;
-
- /// Clear the contents of the map
+
+ /// Clear the contents of the map
void clear();
- /// Get the key at the specified index
- UnownedStringSlice getKeyAt(CountIndex index) const { return m_pool.getSlice(StringSlicePool::Handle(index)); }
- /// Get the value at the specified index
+ /// Get the key at the specified index
+ UnownedStringSlice getKeyAt(CountIndex index) const
+ {
+ return m_pool.getSlice(StringSlicePool::Handle(index));
+ }
+ /// Get the value at the specified index
Index& getValueAt(CountIndex index) { return m_indexMap[index]; }
- /// Get the amount of key,value pairs
+ /// Get the amount of key,value pairs
Index getCount() { return m_indexMap.getCount(); }
- /// Ctor
- StringSliceIndexMap() :
- m_pool(StringSlicePool::Style::Empty)
+ /// Ctor
+ StringSliceIndexMap()
+ : m_pool(StringSlicePool::Style::Empty)
{
}
protected:
- StringSlicePool m_pool; ///< Pool holds the substrings
- List<Index> m_indexMap; ///< Maps a pool index to the output index
+ StringSlicePool m_pool; ///< Pool holds the substrings
+ List<Index> m_indexMap; ///< Maps a pool index to the output index
};
// ---------------------------------------------------------------------------
@@ -73,6 +75,6 @@ KeyValuePair<UnownedStringSlice, Index> StringSliceIndexMap::getAt(CountIndex co
return pair;
}
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-string-slice-pool.cpp b/source/core/slang-string-slice-pool.cpp
index 142952855..0c0ada09f 100644
--- a/source/core/slang-string-slice-pool.cpp
+++ b/source/core/slang-string-slice-pool.cpp
@@ -1,22 +1,21 @@
#include "slang-string-slice-pool.h"
-namespace Slang {
+namespace Slang
+{
/* static */ const StringSlicePool::Handle StringSlicePool::kNullHandle;
/* static */ const StringSlicePool::Handle StringSlicePool::kEmptyHandle;
-/* static */const Index StringSlicePool::kDefaultHandlesCount;
+/* static */ const Index StringSlicePool::kDefaultHandlesCount;
-StringSlicePool::StringSlicePool(Style style) :
- m_style(style),
- m_arena(1024)
+StringSlicePool::StringSlicePool(Style style)
+ : m_style(style), m_arena(1024)
{
clear();
}
-StringSlicePool::StringSlicePool(const ThisType& rhs):
- m_style(rhs.m_style),
- m_arena(1024)
+StringSlicePool::StringSlicePool(const ThisType& rhs)
+ : m_style(rhs.m_style), m_arena(1024)
{
// Set with rhs
_set(rhs);
@@ -42,7 +41,7 @@ void StringSlicePool::_set(const ThisType& rhs)
if (count == 0)
return;
-
+
// We need the same amount of slices
m_slices.setCount(count);
@@ -117,19 +116,19 @@ void StringSlicePool::clear()
switch (m_style)
{
- case Style::Default:
+ case Style::Default:
{
// Add the defaults
m_slices.setCount(2);
m_slices[0] = UnownedStringSlice((const char*)nullptr, (const char*)nullptr);
m_slices[1] = UnownedStringSlice::fromLiteral("");
-
+
// Add the empty entry
m_map.add(m_slices[1], kEmptyHandle);
break;
}
- case Style::Empty:
+ case Style::Empty:
{
// There are no defaults
m_slices.clear();
@@ -155,7 +154,9 @@ StringSlicePool::Handle StringSlicePool::add(const Slice& slice)
}
// Create a scoped copy
- UnownedStringSlice scopePath(m_arena.allocateString(slice.begin(), slice.getLength()), slice.getLength());
+ UnownedStringSlice scopePath(
+ m_arena.allocateString(slice.begin(), slice.getLength()),
+ slice.getLength());
const auto index = m_slices.getCount();
@@ -176,7 +177,9 @@ bool StringSlicePool::findOrAdd(const Slice& slice, Handle& outHandle)
// Need to add.
// Make a copy stored in the arena
- UnownedStringSlice scopeSlice(m_arena.allocateString(slice.begin(), slice.getLength()), slice.getLength());
+ UnownedStringSlice scopeSlice(
+ m_arena.allocateString(slice.begin(), slice.getLength()),
+ slice.getLength());
// Add using the arenas copy
Handle newHandle = Handle(m_slices.getCount());
@@ -196,12 +199,12 @@ StringSlicePool::Handle StringSlicePool::add(StringRepresentation* stringRep)
}
return add(StringRepresentation::asSlice(stringRep));
}
-
+
StringSlicePool::Handle StringSlicePool::add(const char* chars)
{
switch (m_style)
{
- case Style::Default:
+ case Style::Default:
{
if (!chars)
{
@@ -213,7 +216,7 @@ StringSlicePool::Handle StringSlicePool::add(const char* chars)
}
break;
}
- case Style::Empty:
+ case Style::Empty:
{
if (chars == nullptr)
{
@@ -223,7 +226,7 @@ StringSlicePool::Handle StringSlicePool::add(const char* chars)
}
}
}
-
+
return add(UnownedStringSlice(chars));
}
diff --git a/source/core/slang-string-slice-pool.h b/source/core/slang-string-slice-pool.h
index f50ac8dde..87ca18e16 100644
--- a/source/core/slang-string-slice-pool.h
+++ b/source/core/slang-string-slice-pool.h
@@ -1,14 +1,14 @@
#ifndef SLANG_CORE_STRING_SLICE_POOL_H
#define SLANG_CORE_STRING_SLICE_POOL_H
-#include "slang-string.h"
-
+#include "slang-array-view.h"
+#include "slang-dictionary.h"
#include "slang-list.h"
#include "slang-memory-arena.h"
-#include "slang-dictionary.h"
-#include "slang-array-view.h"
+#include "slang-string.h"
-namespace Slang {
+namespace Slang
+{
/* Holds a unique set of slices.
@@ -17,14 +17,14 @@ Note that all slices (except kNullHandle) are stored with terminating zeros.
The default handles kNullHandle, kEmptyHandle can only be used on a StringSlicePool
initialized with the Style::Default. Not doing so will return an undefined result.
-TODO(JS):
+TODO(JS):
An argument could be made to make different classes, perhaps deriving from a base class
that exhibited the two behaviors. That doing so would make the default handles defined
for that class for example.
This is a little awkward in practice, because behavior of some methods need to change
(like adding a c string with nullptr, or clearing, as well as some other perhaps less necessary
-optimizations). This could be achieved via virtual functions, but this all seems overkill.
+optimizations). This could be achieved via virtual functions, but this all seems overkill.
*/
class StringSlicePool
{
@@ -34,57 +34,58 @@ public:
enum class Style
{
- Default, ///< Default style - has default handles (like kNullHandle and kEmptyHandle)
- Empty, ///< Empty style - has no handles by default. Using default handles will likely produce the wrong result.
+ Default, ///< Default style - has default handles (like kNullHandle and kEmptyHandle)
+ Empty, ///< Empty style - has no handles by default. Using default handles will likely
+ ///< produce the wrong result.
};
enum class Handle : HandleIntegral;
typedef UnownedStringSlice Slice;
- /// The following default handles *only* apply if constructed with the Style::Default
+ /// The following default handles *only* apply if constructed with the Style::Default
- /// Handle of 0 is null. If accessed will be returned as the empty string with nullptr the chars
+ /// Handle of 0 is null. If accessed will be returned as the empty string with nullptr the chars
static const Handle kNullHandle = Handle(0);
- /// Handle of 1 is the empty string.
+ /// Handle of 1 is the empty string.
static const Handle kEmptyHandle = Handle(1);
static const Index kDefaultHandlesCount = 2;
- /// Returns the index of a slice, if contained, or -1 if not found
+ /// Returns the index of a slice, if contained, or -1 if not found
Index findIndex(const Slice& slice) const;
- /// True if has the slice
+ /// True if has the slice
bool has(const Slice& slice) { return findIndex(slice) >= 0; }
- /// Add a slice
+ /// Add a slice
Handle add(const Slice& slice);
- /// Add from a string
+ /// Add from a string
Handle add(const char* chars);
- /// Add a StringRepresentation
+ /// Add a StringRepresentation
Handle add(StringRepresentation* string);
- /// Add a string
+ /// Add a string
Handle add(const String& string) { return add(string.getUnownedSlice()); }
- /// Add and get the result as a slice
+ /// Add and get the result as a slice
Slice addAndGetSlice(const Slice& slice) { return getSlice(add(slice)); }
Slice addAndGetSlice(const char* chars) { return getSlice(add(chars)); }
Slice addAndGetSlice(const String& string) { return getSlice(add(string)); }
- /// Returns true if found
+ /// Returns true if found
bool findOrAdd(const Slice& slice, Handle& outHandle);
- /// Empty contents
+ /// Empty contents
void clear();
- /// Get the slice from the handle
+ /// Get the slice from the handle
const UnownedStringSlice& getSlice(Handle handle) const { return m_slices[UInt(handle)]; }
- /// Get all the slices
+ /// Get all the slices
const List<UnownedStringSlice>& getSlices() const { return m_slices; }
- /// Get the number of slices
+ /// Get the number of slices
Index getSlicesCount() const { return m_slices.getCount(); }
- /// Returns true if the handle is a default one. Only meaningful on a Style::Default.
+ /// Returns true if the handle is a default one. Only meaningful on a Style::Default.
bool isDefaultHandle(Handle handle) const
{
SLANG_ASSERT(
@@ -94,30 +95,33 @@ public:
return Index(handle) < kDefaultHandlesCount;
}
- /// Convert a handle to and index. (A handle is just an index!)
+ /// Convert a handle to and index. (A handle is just an index!)
static Index asIndex(Handle handle) { return Index(handle); }
-
- /// Get the style of the pool
+
+ /// Get the style of the pool
Style getStyle() const { return m_style; }
- /// Get all the added slices (does not have default slices, if there are any)
- ConstArrayView<UnownedStringSlice> getAdded() const;
+ /// Get all the added slices (does not have default slices, if there are any)
+ ConstArrayView<UnownedStringSlice> getAdded() const;
- /// Get the index of the first added handle
- Index getFirstAddedIndex() const { return m_style == Style::Default ? kDefaultHandlesCount : 0; }
+ /// Get the index of the first added handle
+ Index getFirstAddedIndex() const
+ {
+ return m_style == Style::Default ? kDefaultHandlesCount : 0;
+ }
- /// Swap this with rhs
+ /// Swap this with rhs
void swapWith(ThisType& rhs);
- /// True if the pools are identical. Same style, same slices in the same order.
+ /// True if the pools are identical. Same style, same slices in the same order.
bool operator==(const ThisType& rhs) const;
- /// Copy ctor
+ /// Copy ctor
StringSlicePool(const ThisType& rhs);
- /// Assignment
+ /// Assignment
void operator=(const ThisType& rhs);
- /// Ctor
+ /// Ctor
explicit StringSlicePool(Style style);
protected:
diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp
index 79f7307dc..1f67089a5 100644
--- a/source/core/slang-string-util.cpp
+++ b/source/core/slang-string-util.cpp
@@ -1,15 +1,18 @@
#include "slang-string-util.h"
#include "slang-blob.h"
-
#include "slang-char-util.h"
#include "slang-text-io.h"
-namespace Slang {
+namespace Slang
+{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!
-/* static */bool StringUtil::areAllEqual(const List<UnownedStringSlice>& a, const List<UnownedStringSlice>& b, EqualFn equalFn)
+/* static */ bool StringUtil::areAllEqual(
+ const List<UnownedStringSlice>& a,
+ const List<UnownedStringSlice>& b,
+ EqualFn equalFn)
{
if (a.getCount() != b.getCount())
{
@@ -27,7 +30,11 @@ namespace Slang {
return true;
}
-/* static */bool StringUtil::areAllEqualWithSplit(const UnownedStringSlice& a, const UnownedStringSlice& b, char splitChar, EqualFn equalFn)
+/* static */ bool StringUtil::areAllEqualWithSplit(
+ const UnownedStringSlice& a,
+ const UnownedStringSlice& b,
+ char splitChar,
+ EqualFn equalFn)
{
List<UnownedStringSlice> slicesA, slicesB;
StringUtil::split(a, splitChar, slicesA);
@@ -35,14 +42,17 @@ namespace Slang {
return areAllEqual(slicesA, slicesB, equalFn);
}
-/* static */void StringUtil::appendSplitOnWhitespace(const UnownedStringSlice& in, List<UnownedStringSlice>& outSlices)
+/* static */ void StringUtil::appendSplitOnWhitespace(
+ const UnownedStringSlice& in,
+ List<UnownedStringSlice>& outSlices)
{
const char* start = in.begin();
const char* end = in.end();
// Skip any at the start
- while (start < end && CharUtil::isWhitespace(*start)) start++;
-
+ while (start < end && CharUtil::isWhitespace(*start))
+ start++;
+
while (start < end)
{
// Find all the non white space in a run
@@ -59,11 +69,15 @@ namespace Slang {
start = cur + 1;
// Skip the split
- while (start < end && CharUtil::isWhitespace(*start)) start++;
+ while (start < end && CharUtil::isWhitespace(*start))
+ start++;
}
}
-/* static */void StringUtil::appendSplit(const UnownedStringSlice& in, char splitChar, List<UnownedStringSlice>& outSlices)
+/* static */ void StringUtil::appendSplit(
+ const UnownedStringSlice& in,
+ char splitChar,
+ List<UnownedStringSlice>& outSlices)
{
const char* start = in.begin();
const char* end = in.end();
@@ -85,7 +99,10 @@ namespace Slang {
}
}
-/* static */void StringUtil::appendSplit(const UnownedStringSlice& in, const UnownedStringSlice& splitSlice, List<UnownedStringSlice>& outSlices)
+/* static */ void StringUtil::appendSplit(
+ const UnownedStringSlice& in,
+ const UnownedStringSlice& splitSlice,
+ List<UnownedStringSlice>& outSlices)
{
const Index splitLen = splitSlice.getLength();
@@ -129,25 +146,37 @@ namespace Slang {
}
}
-/* static */void StringUtil::split(const UnownedStringSlice& in, char splitChar, List<UnownedStringSlice>& outSlices)
+/* static */ void StringUtil::split(
+ const UnownedStringSlice& in,
+ char splitChar,
+ List<UnownedStringSlice>& outSlices)
{
outSlices.clear();
appendSplit(in, splitChar, outSlices);
}
-/* static */void StringUtil::split(const UnownedStringSlice& in, const UnownedStringSlice& splitSlice, List<UnownedStringSlice>& outSlices)
+/* static */ void StringUtil::split(
+ const UnownedStringSlice& in,
+ const UnownedStringSlice& splitSlice,
+ List<UnownedStringSlice>& outSlices)
{
outSlices.clear();
appendSplit(in, splitSlice, outSlices);
}
-/* static */void StringUtil::splitOnWhitespace(const UnownedStringSlice& in, List<UnownedStringSlice>& outSlices)
+/* static */ void StringUtil::splitOnWhitespace(
+ const UnownedStringSlice& in,
+ List<UnownedStringSlice>& outSlices)
{
outSlices.clear();
appendSplitOnWhitespace(in, outSlices);
}
-/* static */Index StringUtil::split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices)
+/* static */ Index StringUtil::split(
+ const UnownedStringSlice& in,
+ char splitChar,
+ Index maxSlices,
+ UnownedStringSlice* outSlices)
{
Index index = 0;
@@ -173,7 +202,12 @@ namespace Slang {
return index;
}
-/* static */SlangResult StringUtil::split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices, Index& outSlicesCount)
+/* static */ SlangResult StringUtil::split(
+ const UnownedStringSlice& in,
+ char splitChar,
+ Index maxSlices,
+ UnownedStringSlice* outSlices,
+ Index& outSlicesCount)
{
const Index sliceCount = split(in, splitChar, maxSlices, outSlices);
if (sliceCount == maxSlices && sliceCount > 0)
@@ -188,12 +222,15 @@ namespace Slang {
return SLANG_OK;
}
-/* static */void StringUtil::join(const List<String>& values, char separator, StringBuilder& out)
+/* static */ void StringUtil::join(const List<String>& values, char separator, StringBuilder& out)
{
join(values, UnownedStringSlice(&separator, 1), out);
}
-/* static */void StringUtil::join(const List<String>& values, const UnownedStringSlice& separator, StringBuilder& out)
+/* static */ void StringUtil::join(
+ const List<String>& values,
+ const UnownedStringSlice& separator,
+ StringBuilder& out)
{
const Index count = values.getCount();
if (count <= 0)
@@ -208,12 +245,20 @@ namespace Slang {
}
}
-/* static */void StringUtil::join(const UnownedStringSlice* values, Index valueCount, char separator, StringBuilder& out)
+/* static */ void StringUtil::join(
+ const UnownedStringSlice* values,
+ Index valueCount,
+ char separator,
+ StringBuilder& out)
{
join(values, valueCount, UnownedStringSlice(&separator, 1), out);
}
-/* static */void StringUtil::join(const UnownedStringSlice* values, Index valueCount, const UnownedStringSlice& separator, StringBuilder& out)
+/* static */ void StringUtil::join(
+ const UnownedStringSlice* values,
+ Index valueCount,
+ const UnownedStringSlice& separator,
+ StringBuilder& out)
{
if (valueCount <= 0)
{
@@ -227,7 +272,10 @@ namespace Slang {
}
}
-/* static */Index StringUtil::indexOfInSplit(const UnownedStringSlice& in, char splitChar, const UnownedStringSlice& find)
+/* static */ Index StringUtil::indexOfInSplit(
+ const UnownedStringSlice& in,
+ char splitChar,
+ const UnownedStringSlice& find)
{
const char* start = in.begin();
const char* end = in.end();
@@ -253,7 +301,10 @@ namespace Slang {
return -1;
}
-UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char splitChar, Index index)
+UnownedStringSlice StringUtil::getAtInSplit(
+ const UnownedStringSlice& in,
+ char splitChar,
+ Index index)
{
const char* start = in.begin();
const char* end = in.end();
@@ -279,16 +330,20 @@ UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char s
return UnownedStringSlice();
}
-/* static */size_t StringUtil::calcFormattedSize(const char* format, va_list args)
+/* static */ size_t StringUtil::calcFormattedSize(const char* format, va_list args)
{
#if SLANG_WINDOWS_FAMILY
return _vscprintf(format, args);
#else
- return vsnprintf(nullptr, 0, format, args);
+ return vsnprintf(nullptr, 0, format, args);
#endif
}
-/* static */void StringUtil::calcFormatted(const char* format, va_list args, size_t numChars, char* dst)
+/* static */ void StringUtil::calcFormatted(
+ const char* format,
+ va_list args,
+ size_t numChars,
+ char* dst)
{
#if SLANG_WINDOWS_FAMILY
vsnprintf_s(dst, numChars + 1, _TRUNCATE, format, args);
@@ -297,7 +352,7 @@ UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char s
#endif
}
-/* static */void StringUtil::append(const char* format, va_list args, StringBuilder& buf)
+/* static */ void StringUtil::append(const char* format, va_list args, StringBuilder& buf)
{
// Calculate the size required (not including terminating 0)
size_t numChars;
@@ -315,7 +370,7 @@ UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char s
buf.appendInPlace(dst, numChars);
}
-/* static */void StringUtil::appendFormat(StringBuilder& buf, const char* format, ...)
+/* static */ void StringUtil::appendFormat(StringBuilder& buf, const char* format, ...)
{
va_list args;
va_start(args, format);
@@ -323,7 +378,7 @@ UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char s
va_end(args);
}
-/* static */String StringUtil::makeStringWithFormat(const char* format, ...)
+/* static */ String StringUtil::makeStringWithFormat(const char* format, ...)
{
StringBuilder builder;
@@ -335,7 +390,7 @@ UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char s
return builder;
}
-/* static */UnownedStringSlice StringUtil::getSlice(ISlangBlob* blob)
+/* static */ UnownedStringSlice StringUtil::getSlice(ISlangBlob* blob)
{
if (blob)
{
@@ -343,7 +398,8 @@ UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char s
if (size > 0)
{
const char* contents = (const char*)blob->getBufferPointer();
- // Check it has terminating 0, if it has we skip it, because slices do not need zero termination
+ // Check it has terminating 0, if it has we skip it, because slices do not need zero
+ // termination
if (contents[size - 1] == 0)
{
size--;
@@ -354,7 +410,7 @@ UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char s
return UnownedStringSlice();
}
-/* static */String StringUtil::getString(ISlangBlob* blob)
+/* static */ String StringUtil::getString(ISlangBlob* blob)
{
return getSlice(blob);
}
@@ -364,7 +420,10 @@ ComPtr<ISlangBlob> StringUtil::createStringBlob(const String& string)
return StringBlob::create(string);
}
-/* static */String StringUtil::calcCharReplaced(const UnownedStringSlice& slice, char fromChar, char toChar)
+/* static */ String StringUtil::calcCharReplaced(
+ const UnownedStringSlice& slice,
+ char fromChar,
+ char toChar)
{
if (fromChar == toChar)
{
@@ -387,12 +446,17 @@ ComPtr<ISlangBlob> StringUtil::createStringBlob(const String& string)
return builder;
}
-/* static */String StringUtil::calcCharReplaced(const String& string, char fromChar, char toChar)
+/* static */ String StringUtil::calcCharReplaced(const String& string, char fromChar, char toChar)
{
- return (fromChar == toChar || string.indexOf(fromChar) == Index(-1)) ? string : calcCharReplaced(string.getUnownedSlice(), fromChar, toChar);
+ return (fromChar == toChar || string.indexOf(fromChar) == Index(-1))
+ ? string
+ : calcCharReplaced(string.getUnownedSlice(), fromChar, toChar);
}
-String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr, UnownedStringSlice replacement)
+String StringUtil::replaceAll(
+ UnownedStringSlice text,
+ UnownedStringSlice subStr,
+ UnownedStringSlice replacement)
{
StringBuilder builder;
for (Index i = 0; i < text.getLength();)
@@ -417,7 +481,9 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
}
-/* static */void StringUtil::appendStandardLines(const UnownedStringSlice& text, StringBuilder& out)
+/* static */ void StringUtil::appendStandardLines(
+ const UnownedStringSlice& text,
+ StringBuilder& out)
{
const char* cur = text.begin();
const char* start = cur;
@@ -428,25 +494,25 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
const char c = *cur;
switch (c)
{
- case '\n':
+ case '\n':
{
++cur;
if (cur < end && *cur == '\r')
{
// If we have following \r, we should append with \n
- // Append (including \n)
+ // Append (including \n)
out.append(start, cur);
// Skip the \r
start = ++cur;
}
else
{
- // If not, we don't need to append because just \n is 'standard', and everything remaining
- // is appended at the end
+ // If not, we don't need to append because just \n is 'standard', and everything
+ // remaining is appended at the end
}
break;
}
- case '\r':
+ case '\r':
{
out.append(start, cur);
out.appendChar('\n');
@@ -457,7 +523,7 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
start = cur;
break;
}
- default:
+ default:
{
cur++;
break;
@@ -471,10 +537,10 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
}
}
-/* static */bool StringUtil::extractLine(UnownedStringSlice& ioText, UnownedStringSlice& outLine)
+/* static */ bool StringUtil::extractLine(UnownedStringSlice& ioText, UnownedStringSlice& outLine)
{
- char const*const begin = ioText.begin();
- char const*const end = ioText.end();
+ char const* const begin = ioText.begin();
+ char const* const end = ioText.end();
// If we have hit the end then return the 'special' terminator
if (begin == nullptr)
@@ -489,10 +555,11 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
int c = *cursor++;
switch (c)
{
- case '\r': case '\n':
+ case '\r':
+ case '\n':
{
// Remember the end of the line
- const char*const lineEnd = cursor - 1;
+ const char* const lineEnd = cursor - 1;
// When we see a line-break character we need
// to record the line break, but we also need
@@ -510,8 +577,7 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
outLine = UnownedStringSlice(begin, lineEnd);
return true;
}
- default:
- break;
+ default: break;
}
}
@@ -525,7 +591,9 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
return true;
}
-/* static */void StringUtil::calcLines(const UnownedStringSlice& textIn, List<UnownedStringSlice>& outLines)
+/* static */ void StringUtil::calcLines(
+ const UnownedStringSlice& textIn,
+ List<UnownedStringSlice>& outLines)
{
outLines.clear();
UnownedStringSlice text(textIn), line;
@@ -535,7 +603,7 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
}
}
-/* static */UnownedStringSlice StringUtil::trimEndOfLine(const UnownedStringSlice& line)
+/* static */ UnownedStringSlice StringUtil::trimEndOfLine(const UnownedStringSlice& line)
{
// Strip CR/LF from end of line if present
@@ -557,10 +625,12 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
return line.head(Index(end - begin));
}
-/* static */bool StringUtil::areLinesEqual(const UnownedStringSlice& inA, const UnownedStringSlice& inB)
+/* static */ bool StringUtil::areLinesEqual(
+ const UnownedStringSlice& inA,
+ const UnownedStringSlice& inB)
{
UnownedStringSlice a(inA), b(inB), lineA, lineB;
-
+
while (true)
{
const auto hasLineA = extractLine(a, lineA);
@@ -579,7 +649,7 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
}
}
-/* static */SlangResult StringUtil::parseDouble(const UnownedStringSlice& text, double& out)
+/* static */ SlangResult StringUtil::parseDouble(const UnownedStringSlice& text, double& out)
{
const Index bufSize = 32;
@@ -606,7 +676,7 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
return SLANG_OK;
}
-/* static */SlangResult StringUtil::parseInt(const UnownedStringSlice& in, Int& outValue)
+/* static */ SlangResult StringUtil::parseInt(const UnownedStringSlice& in, Int& outValue)
{
const char* cur = in.begin();
const char* end = in.end();
@@ -620,7 +690,7 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
int radix = 10;
auto getDigit = CharUtil::getDecimalDigitValue;
- if (cur+1 < end && *cur == '0' && (*(cur+1) == 'x' || *(cur+1) == 'X'))
+ if (cur + 1 < end && *cur == '0' && (*(cur + 1) == 'x' || *(cur + 1) == 'X'))
{
radix = 16;
getDigit = CharUtil::getHexDigitValue;
@@ -632,7 +702,7 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
{
return SLANG_FAIL;
}
-
+
Int value = 0;
// Do the digits
for (; cur < end; ++cur)
@@ -649,7 +719,7 @@ String StringUtil::replaceAll(UnownedStringSlice text, UnownedStringSlice subStr
return SLANG_OK;
}
-/* static */SlangResult StringUtil::parseInt64(const UnownedStringSlice& text, int64_t& out)
+/* static */ SlangResult StringUtil::parseInt64(const UnownedStringSlice& text, int64_t& out)
{
bool negate = false;
diff --git a/source/core/slang-string-util.h b/source/core/slang-string-util.h
index c0a8f6973..9e7b2d65a 100644
--- a/source/core/slang-string-util.h
+++ b/source/core/slang-string-util.h
@@ -1,137 +1,202 @@
#ifndef SLANG_CORE_STRING_UTIL_H
#define SLANG_CORE_STRING_UTIL_H
-#include "slang-string.h"
+#include "slang-com-helper.h"
+#include "slang-com-ptr.h"
#include "slang-list.h"
+#include "slang-string.h"
#include <stdarg.h>
-#include "slang-com-helper.h"
-#include "slang-com-ptr.h"
-
-namespace Slang {
+namespace Slang
+{
struct StringUtil
{
typedef bool (*EqualFn)(const UnownedStringSlice& a, const UnownedStringSlice& b);
- /// True if the splits of a and b (via splitChar) are all equal as compared with the equalFn function
- static bool areAllEqualWithSplit(const UnownedStringSlice& a, const UnownedStringSlice& b, char splitChar, EqualFn equalFn);
-
- /// True if all slices in match are all equal as compared with the equalFn function
- static bool areAllEqual(const List<UnownedStringSlice>& a, const List<UnownedStringSlice>& b, EqualFn equalFn);
-
- /// Split in, by specified splitChar into slices out
- /// Slices contents will directly address into in, so contents will only stay valid as long as in does.
- static void split(const UnownedStringSlice& in, char splitChar, List<UnownedStringSlice>& slicesOut);
- /// Split in by the specified splitSlice
- /// Slices contents will directly address into in, so contents will only stay valid as long as in does.
- static void split(const UnownedStringSlice& in, const UnownedStringSlice& splitSlice, List<UnownedStringSlice>& slicesOut);
-
- /// Splits in into outSlices, up to maxSlices. May not consume all of in (for example if it runs out of space).
- static Index split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices);
- /// Splits into outSlices up to maxSlices. Returns SLANG_OK if of 'in' consumed.
- static SlangResult split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices, Index& outSlicesCount);
- /// Splits on white space
- static void splitOnWhitespace(const UnownedStringSlice& in, List<UnownedStringSlice>& slicesOut);
-
- /// Split in, by specified splitChar append into slices out
- /// Slices contents will directly address into in, so contents will only stay valid as long as in does.
- static void appendSplit(const UnownedStringSlice& in, char splitChar, List<UnownedStringSlice>& slicesOut);
- /// Split in by the specified splitSlice
- /// Slices contents will directly address into in, so contents will only stay valid as long as in does.
- static void appendSplit(const UnownedStringSlice& in, const UnownedStringSlice& splitSlice, List<UnownedStringSlice>& slicesOut);
-
- /// appends splits on white space
- static void appendSplitOnWhitespace(const UnownedStringSlice& in, List<UnownedStringSlice>& slicesOut);
-
- /// Append the joining of in items, separated by 'separator' onto out
+ /// True if the splits of a and b (via splitChar) are all equal as compared with the equalFn
+ /// function
+ static bool areAllEqualWithSplit(
+ const UnownedStringSlice& a,
+ const UnownedStringSlice& b,
+ char splitChar,
+ EqualFn equalFn);
+
+ /// True if all slices in match are all equal as compared with the equalFn function
+ static bool areAllEqual(
+ const List<UnownedStringSlice>& a,
+ const List<UnownedStringSlice>& b,
+ EqualFn equalFn);
+
+ /// Split in, by specified splitChar into slices out
+ /// Slices contents will directly address into in, so contents will only stay valid as long as
+ /// in does.
+ static void split(
+ const UnownedStringSlice& in,
+ char splitChar,
+ List<UnownedStringSlice>& slicesOut);
+ /// Split in by the specified splitSlice
+ /// Slices contents will directly address into in, so contents will only stay valid as long as
+ /// in does.
+ static void split(
+ const UnownedStringSlice& in,
+ const UnownedStringSlice& splitSlice,
+ List<UnownedStringSlice>& slicesOut);
+
+ /// Splits in into outSlices, up to maxSlices. May not consume all of in (for example if it runs
+ /// out of space).
+ static Index split(
+ const UnownedStringSlice& in,
+ char splitChar,
+ Index maxSlices,
+ UnownedStringSlice* outSlices);
+ /// Splits into outSlices up to maxSlices. Returns SLANG_OK if of 'in' consumed.
+ static SlangResult split(
+ const UnownedStringSlice& in,
+ char splitChar,
+ Index maxSlices,
+ UnownedStringSlice* outSlices,
+ Index& outSlicesCount);
+ /// Splits on white space
+ static void splitOnWhitespace(
+ const UnownedStringSlice& in,
+ List<UnownedStringSlice>& slicesOut);
+
+ /// Split in, by specified splitChar append into slices out
+ /// Slices contents will directly address into in, so contents will only stay valid as long as
+ /// in does.
+ static void appendSplit(
+ const UnownedStringSlice& in,
+ char splitChar,
+ List<UnownedStringSlice>& slicesOut);
+ /// Split in by the specified splitSlice
+ /// Slices contents will directly address into in, so contents will only stay valid as long as
+ /// in does.
+ static void appendSplit(
+ const UnownedStringSlice& in,
+ const UnownedStringSlice& splitSlice,
+ List<UnownedStringSlice>& slicesOut);
+
+ /// appends splits on white space
+ static void appendSplitOnWhitespace(
+ const UnownedStringSlice& in,
+ List<UnownedStringSlice>& slicesOut);
+
+ /// Append the joining of in items, separated by 'separator' onto out
static void join(const List<String>& in, char separator, StringBuilder& out);
- static void join(const List<String>& in, const UnownedStringSlice& separator, StringBuilder& out);
-
- static void join(const UnownedStringSlice* values, Index valueCount, char separator, StringBuilder& out);
- static void join(const UnownedStringSlice* values, Index valueCount, const UnownedStringSlice& separator, StringBuilder& out);
-
- /// Equivalent to doing a split and then finding the index of 'find' on the array
- /// Returns -1 if not found
- static Index indexOfInSplit(const UnownedStringSlice& in, char splitChar, const UnownedStringSlice& find);
-
- /// Given the entry at the split index specified.
- /// Will return slice with begin() == nullptr if not found or input has begin() == nullptr)
- static UnownedStringSlice getAtInSplit(const UnownedStringSlice& in, char splitChar, Index index);
-
- /// Returns the size in bytes needed to hold the formatted string using the specified args, NOT including a terminating 0
- /// NOTE! The caller *should* assume this will consume the va_list (use va_copy to make a copy to be consumed)
+ static void join(
+ const List<String>& in,
+ const UnownedStringSlice& separator,
+ StringBuilder& out);
+
+ static void join(
+ const UnownedStringSlice* values,
+ Index valueCount,
+ char separator,
+ StringBuilder& out);
+ static void join(
+ const UnownedStringSlice* values,
+ Index valueCount,
+ const UnownedStringSlice& separator,
+ StringBuilder& out);
+
+ /// Equivalent to doing a split and then finding the index of 'find' on the array
+ /// Returns -1 if not found
+ static Index indexOfInSplit(
+ const UnownedStringSlice& in,
+ char splitChar,
+ const UnownedStringSlice& find);
+
+ /// Given the entry at the split index specified.
+ /// Will return slice with begin() == nullptr if not found or input has begin() == nullptr)
+ static UnownedStringSlice getAtInSplit(
+ const UnownedStringSlice& in,
+ char splitChar,
+ Index index);
+
+ /// Returns the size in bytes needed to hold the formatted string using the specified args, NOT
+ /// including a terminating 0 NOTE! The caller *should* assume this will consume the va_list
+ /// (use va_copy to make a copy to be consumed)
static size_t calcFormattedSize(const char* format, va_list args);
- /// Calculate the formatted string using the specified args.
- /// NOTE! The caller *should* assume this will consume the va_list
- /// The buffer should be at least calcFormattedSize + 1 bytes. The +1 is needed because a terminating 0 is written.
+ /// Calculate the formatted string using the specified args.
+ /// NOTE! The caller *should* assume this will consume the va_list
+ /// The buffer should be at least calcFormattedSize + 1 bytes. The +1 is needed because a
+ /// terminating 0 is written.
static void calcFormatted(const char* format, va_list args, size_t numChars, char* dst);
- /// Appends formatted string with args into buf
+ /// Appends formatted string with args into buf
static void append(const char* format, va_list args, StringBuilder& buf);
- /// Appends the formatted string with specified trailing args
+ /// Appends the formatted string with specified trailing args
static void appendFormat(StringBuilder& buf, const char* format, ...);
- /// Create a string from the format string applying args (like sprintf)
+ /// Create a string from the format string applying args (like sprintf)
static String makeStringWithFormat(const char* format, ...);
- /// Given a string held in a blob, returns as a String
- /// Returns an empty string if blob is nullptr
+ /// Given a string held in a blob, returns as a String
+ /// Returns an empty string if blob is nullptr
static String getString(ISlangBlob* blob);
static UnownedStringSlice getSlice(ISlangBlob* blob);
- /// Given a string or slice, replaces all instances of fromChar with toChar
+ /// Given a string or slice, replaces all instances of fromChar with toChar
static String calcCharReplaced(const UnownedStringSlice& slice, char fromChar, char toChar);
static String calcCharReplaced(const String& string, char fromChar, char toChar);
-
- /// Replaces all occurrances of subStr with replacement.
- static String replaceAll(UnownedStringSlice text, UnownedStringSlice subStr, UnownedStringSlice replacement);
- /// Create a blob from a string
+ /// Replaces all occurrances of subStr with replacement.
+ static String replaceAll(
+ UnownedStringSlice text,
+ UnownedStringSlice subStr,
+ UnownedStringSlice replacement);
+
+ /// Create a blob from a string
static ComPtr<ISlangBlob> createStringBlob(const String& string);
- /// Given input text outputs with standardized line endings. Ie \n\r -> \n
+ /// Given input text outputs with standardized line endings. Ie \n\r -> \n
static void appendStandardLines(const UnownedStringSlice& text, StringBuilder& out);
- /// Extracts a line and stores the remaining text in ioText, and the line in outLine. Returns true if has a line.
- ///
- /// As well as indicating end of text with the return value, at the end of all the text a 'special' null UnownedStringSlice with a null 'begin'
- /// pointer is also returned as the outLine.
- /// ioText will be modified to contain the remaining text, starting at the beginning of the next line.
- /// As an empty final line is still a line, the special null UnownedStringSlice is the last value ioText after the last valid line is returned.
- ///
- /// NOTE! That behavior is as if line terminators (like \n) act as separators. Thus input of "\n" will return *two* lines - an empty line
- /// before and then after the \n.
+ /// Extracts a line and stores the remaining text in ioText, and the line in outLine. Returns
+ /// true if has a line.
+ ///
+ /// As well as indicating end of text with the return value, at the end of all the text a
+ /// 'special' null UnownedStringSlice with a null 'begin' pointer is also returned as the
+ /// outLine. ioText will be modified to contain the remaining text, starting at the beginning of
+ /// the next line. As an empty final line is still a line, the special null UnownedStringSlice
+ /// is the last value ioText after the last valid line is returned.
+ ///
+ /// NOTE! That behavior is as if line terminators (like \n) act as separators. Thus input of
+ /// "\n" will return *two* lines - an empty line before and then after the \n.
static bool extractLine(UnownedStringSlice& ioText, UnownedStringSlice& outLine);
-
- /// Given text, splits into lines stored in outLines. NOTE! That lines is only valid as long as textIn remains valid
+
+ /// Given text, splits into lines stored in outLines. NOTE! That lines is only valid as long as
+ /// textIn remains valid
static void calcLines(const UnownedStringSlice& textIn, List<UnownedStringSlice>& lines);
- /// Given a line that may contain cr/lf, returns the the a slice that doesn't have trailing cr/lf
+ /// Given a line that may contain cr/lf, returns the the a slice that doesn't have trailing
+ /// cr/lf
static UnownedStringSlice trimEndOfLine(const UnownedStringSlice& slice);
- /// Equal if the lines are equal (in effect a way to ignore differences in line breaks)
+ /// Equal if the lines are equal (in effect a way to ignore differences in line breaks)
static bool areLinesEqual(const UnownedStringSlice& a, const UnownedStringSlice& b);
- /// Convert in to int. Returns SLANG_FAIL on error
+ /// Convert in to int. Returns SLANG_FAIL on error
static SlangResult parseInt(const UnownedStringSlice& in, Int& outValue);
- /// Convert ioText into double. Returns SLANG_OK on success.
+ /// Convert ioText into double. Returns SLANG_OK on success.
static SlangResult parseDouble(const UnownedStringSlice& text, double& out);
- /// Convert into int64_t. Returns SLANG_OK on success.
+ /// Convert into int64_t. Returns SLANG_OK on success.
static SlangResult parseInt64(const UnownedStringSlice& text, int64_t& out);
- /// Parse an integer from text starting at pos until the end or the first non-digit char.
- /// Modifies pos to the position where parsing ends.
- /// Returns parsed integer.
+ /// Parse an integer from text starting at pos until the end or the first non-digit char.
+ /// Modifies pos to the position where parsing ends.
+ /// Returns parsed integer.
static int parseIntAndAdvancePos(UnownedStringSlice text, Index& pos);
};
-/* A helper class that allows parsing of lines from text with iteration. Uses StringUtil::extractLine for the actual underlying implementation. */
+/* A helper class that allows parsing of lines from text with iteration. Uses
+ * StringUtil::extractLine for the actual underlying implementation. */
class LineParser
{
public:
@@ -144,25 +209,46 @@ public:
StringUtil::extractLine(m_remaining, m_line);
return *this;
}
- Iterator operator++(int) { Iterator rs = *this; operator++(); return rs; }
+ Iterator operator++(int)
+ {
+ Iterator rs = *this;
+ operator++();
+ return rs;
+ }
- /// Equal if both are at the same m_line address exactly. Handles termination case correctly where line.begin() == nullptr.
- bool operator==(const Iterator& rhs) const { return m_line.begin() == rhs.m_line.begin(); }
- bool operator !=(const Iterator& rhs) const { return !(*this == rhs); }
+ /// Equal if both are at the same m_line address exactly. Handles termination case correctly
+ /// where line.begin() == nullptr.
+ bool operator==(const Iterator& rhs) const { return m_line.begin() == rhs.m_line.begin(); }
+ bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
- /// Ctor
- Iterator(const UnownedStringSlice& line, const UnownedStringSlice& remaining) : m_line(line), m_remaining(remaining) {}
+ /// Ctor
+ Iterator(const UnownedStringSlice& line, const UnownedStringSlice& remaining)
+ : m_line(line), m_remaining(remaining)
+ {
+ }
protected:
UnownedStringSlice m_line;
UnownedStringSlice m_remaining;
};
- Iterator begin() const { UnownedStringSlice remaining(m_text), line; StringUtil::extractLine(remaining, line); return Iterator(line, remaining); }
- Iterator end() const { UnownedStringSlice term(nullptr, nullptr); return Iterator(term, term); }
+ Iterator begin() const
+ {
+ UnownedStringSlice remaining(m_text), line;
+ StringUtil::extractLine(remaining, line);
+ return Iterator(line, remaining);
+ }
+ Iterator end() const
+ {
+ UnownedStringSlice term(nullptr, nullptr);
+ return Iterator(term, term);
+ }
- /// Ctor
- LineParser(const UnownedStringSlice& text) : m_text(text) {}
+ /// Ctor
+ LineParser(const UnownedStringSlice& text)
+ : m_text(text)
+ {
+ }
protected:
UnownedStringSlice m_text;
diff --git a/source/core/slang-string.cpp b/source/core/slang-string.cpp
index 182c6261e..b58d466fa 100644
--- a/source/core/slang-string.cpp
+++ b/source/core/slang-string.cpp
@@ -1,288 +1,292 @@
#include "slang-string.h"
-#include "slang-text-io.h"
#include "slang-char-util.h"
+#include "slang-text-io.h"
namespace Slang
{
- // HACK!
- // JS: Many of the inlined functions of CharUtil just access a global map. That referencing this global is *NOT* enough to
- // link correctly with CharUtil on linux for a shared library. The following call exists to try and force linkage of CharUtil
- // for anything that uses core
- static const auto s_charUtilLink = CharUtil::_ensureLink();
+// HACK!
+// JS: Many of the inlined functions of CharUtil just access a global map. That referencing this
+// global is *NOT* enough to link correctly with CharUtil on linux for a shared library. The
+// following call exists to try and force linkage of CharUtil for anything that uses core
+static const auto s_charUtilLink = CharUtil::_ensureLink();
- // StringRepresentation
+// StringRepresentation
- void StringRepresentation::setContents(const UnownedStringSlice& slice)
- {
- const auto sliceLength = slice.getLength();
- SLANG_ASSERT(sliceLength <= capacity);
+void StringRepresentation::setContents(const UnownedStringSlice& slice)
+{
+ const auto sliceLength = slice.getLength();
+ SLANG_ASSERT(sliceLength <= capacity);
- char* chars = getData();
+ char* chars = getData();
- // Use move (rather than memcpy), because the slice *could* be contained in the StringRepresentation
- ::memmove(chars, slice.begin(), sliceLength * sizeof(char));
- // Zero terminate.
- chars[sliceLength] = 0;
- // Set the length
- length = sliceLength;
- }
+ // Use move (rather than memcpy), because the slice *could* be contained in the
+ // StringRepresentation
+ ::memmove(chars, slice.begin(), sliceLength * sizeof(char));
+ // Zero terminate.
+ chars[sliceLength] = 0;
+ // Set the length
+ length = sliceLength;
+}
- /* static */StringRepresentation* StringRepresentation::create(const UnownedStringSlice& slice)
+/* static */ StringRepresentation* StringRepresentation::create(const UnownedStringSlice& slice)
+{
+ const auto sliceLength = slice.getLength();
+
+ if (sliceLength)
{
- const auto sliceLength = slice.getLength();
+ StringRepresentation* rep = StringRepresentation::createWithLength(sliceLength);
- if (sliceLength)
- {
- StringRepresentation* rep = StringRepresentation::createWithLength(sliceLength);
-
- char* chars = rep->getData();
- ::memcpy(chars, slice.begin(), sizeof(char) * sliceLength);
- chars[sliceLength] = 0;
+ char* chars = rep->getData();
+ ::memcpy(chars, slice.begin(), sizeof(char) * sliceLength);
+ chars[sliceLength] = 0;
- return rep;
- }
- else
- {
- return nullptr;
- }
+ return rep;
}
-
- /* static */StringRepresentation* StringRepresentation::createWithReference(const UnownedStringSlice& slice)
+ else
{
- const auto sliceLength = slice.getLength();
+ return nullptr;
+ }
+}
- if (sliceLength)
- {
- StringRepresentation* rep = StringRepresentation::createWithLength(sliceLength);
- rep->addReference();
+/* static */ StringRepresentation* StringRepresentation::createWithReference(
+ const UnownedStringSlice& slice)
+{
+ const auto sliceLength = slice.getLength();
- char* chars = rep->getData();
- ::memcpy(chars, slice.begin(), sizeof(char) * sliceLength);
- chars[sliceLength] = 0;
+ if (sliceLength)
+ {
+ StringRepresentation* rep = StringRepresentation::createWithLength(sliceLength);
+ rep->addReference();
- return rep;
- }
- else
- {
- return nullptr;
- }
+ char* chars = rep->getData();
+ ::memcpy(chars, slice.begin(), sizeof(char) * sliceLength);
+ chars[sliceLength] = 0;
+
+ return rep;
}
+ else
+ {
+ return nullptr;
+ }
+}
- // OSString
+// OSString
- OSString::OSString()
- : m_begin(nullptr)
- , m_end(nullptr)
- {}
+OSString::OSString()
+ : m_begin(nullptr), m_end(nullptr)
+{
+}
- OSString::OSString(wchar_t* begin, wchar_t* end)
- : m_begin(begin)
- , m_end(end)
- {}
+OSString::OSString(wchar_t* begin, wchar_t* end)
+ : m_begin(begin), m_end(end)
+{
+}
- void OSString::_releaseBuffer()
+void OSString::_releaseBuffer()
+{
+ if (m_begin)
{
- if (m_begin)
- {
- delete[] m_begin;
- }
+ delete[] m_begin;
}
+}
- void OSString::set(const wchar_t* begin, const wchar_t* end)
+void OSString::set(const wchar_t* begin, const wchar_t* end)
+{
+ if (m_begin)
{
- if (m_begin)
- {
- delete[] m_begin;
- m_begin = nullptr;
- m_end = nullptr;
- }
- const size_t len = end - begin;
- if (len > 0)
- {
- // TODO(JS): The allocation is only done this way to be compatible with the buffer being detached from an array
- // This is unfortunate, because it means that the allocation stores the size (and alignment fix), which is a shame because we know the size
- m_begin = new wchar_t[len + 1];
- memcpy(m_begin, begin, len * sizeof(wchar_t));
- // Zero terminate
- m_begin[len] = 0;
- m_end = m_begin + len;
- }
+ delete[] m_begin;
+ m_begin = nullptr;
+ m_end = nullptr;
}
-
- static const wchar_t kEmptyOSString[] = { 0 };
-
- wchar_t const* OSString::begin() const
+ const size_t len = end - begin;
+ if (len > 0)
{
- return m_begin ? m_begin : kEmptyOSString;
+ // TODO(JS): The allocation is only done this way to be compatible with the buffer being
+ // detached from an array This is unfortunate, because it means that the allocation stores
+ // the size (and alignment fix), which is a shame because we know the size
+ m_begin = new wchar_t[len + 1];
+ memcpy(m_begin, begin, len * sizeof(wchar_t));
+ // Zero terminate
+ m_begin[len] = 0;
+ m_end = m_begin + len;
}
+}
- wchar_t const* OSString::end() const
- {
- return m_end ? m_end : kEmptyOSString;
- }
+static const wchar_t kEmptyOSString[] = {0};
- // UnownedStringSlice
+wchar_t const* OSString::begin() const
+{
+ return m_begin ? m_begin : kEmptyOSString;
+}
- bool UnownedStringSlice::startsWith(UnownedStringSlice const& other) const
- {
- UInt thisSize = getLength();
- UInt otherSize = other.getLength();
+wchar_t const* OSString::end() const
+{
+ return m_end ? m_end : kEmptyOSString;
+}
- if (otherSize > thisSize)
- return false;
+// UnownedStringSlice
- return head(otherSize) == other;
- }
+bool UnownedStringSlice::startsWith(UnownedStringSlice const& other) const
+{
+ UInt thisSize = getLength();
+ UInt otherSize = other.getLength();
- bool UnownedStringSlice::startsWith(char const* str) const
- {
- return startsWith(UnownedTerminatedStringSlice(str));
- }
+ if (otherSize > thisSize)
+ return false;
- bool UnownedStringSlice::startsWithCaseInsensitive(UnownedStringSlice const& other) const
- {
- UInt thisSize = getLength();
- UInt otherSize = other.getLength();
+ return head(otherSize) == other;
+}
- if (otherSize > thisSize)
- return false;
+bool UnownedStringSlice::startsWith(char const* str) const
+{
+ return startsWith(UnownedTerminatedStringSlice(str));
+}
- return head(otherSize).caseInsensitiveEquals(other);
- }
+bool UnownedStringSlice::startsWithCaseInsensitive(UnownedStringSlice const& other) const
+{
+ UInt thisSize = getLength();
+ UInt otherSize = other.getLength();
+ if (otherSize > thisSize)
+ return false;
- bool UnownedStringSlice::endsWith(UnownedStringSlice const& other) const
- {
- UInt thisSize = getLength();
- UInt otherSize = other.getLength();
+ return head(otherSize).caseInsensitiveEquals(other);
+}
- if (otherSize > thisSize)
- return false;
- return UnownedStringSlice(
- end() - otherSize, end()) == other;
- }
+bool UnownedStringSlice::endsWith(UnownedStringSlice const& other) const
+{
+ UInt thisSize = getLength();
+ UInt otherSize = other.getLength();
- bool UnownedStringSlice::endsWithCaseInsensitive(UnownedStringSlice const& other) const
- {
- UInt thisSize = getLength();
- UInt otherSize = other.getLength();
+ if (otherSize > thisSize)
+ return false;
- if (otherSize > thisSize)
- return false;
+ return UnownedStringSlice(end() - otherSize, end()) == other;
+}
- return UnownedStringSlice(end() - otherSize, end()).caseInsensitiveEquals(other);
- }
+bool UnownedStringSlice::endsWithCaseInsensitive(UnownedStringSlice const& other) const
+{
+ UInt thisSize = getLength();
+ UInt otherSize = other.getLength();
- bool UnownedStringSlice::endsWith(char const* str) const
- {
- return endsWith(UnownedTerminatedStringSlice(str));
- }
+ if (otherSize > thisSize)
+ return false;
- bool UnownedStringSlice::endsWithCaseInsensitive(char const* str) const
- {
- return endsWithCaseInsensitive(UnownedTerminatedStringSlice(str));
- }
+ return UnownedStringSlice(end() - otherSize, end()).caseInsensitiveEquals(other);
+}
- UnownedStringSlice UnownedStringSlice::trim() const
- {
- const char* start = m_begin;
- const char* end = m_end;
+bool UnownedStringSlice::endsWith(char const* str) const
+{
+ return endsWith(UnownedTerminatedStringSlice(str));
+}
- while (start < end && CharUtil::isHorizontalWhitespace(*start)) start++;
- while (end > start && CharUtil::isHorizontalWhitespace(end[-1])) end--;
- return UnownedStringSlice(start, end);
- }
+bool UnownedStringSlice::endsWithCaseInsensitive(char const* str) const
+{
+ return endsWithCaseInsensitive(UnownedTerminatedStringSlice(str));
+}
- UnownedStringSlice UnownedStringSlice::trimStart() const
- {
- const char* start = m_begin;
+UnownedStringSlice UnownedStringSlice::trim() const
+{
+ const char* start = m_begin;
+ const char* end = m_end;
+
+ while (start < end && CharUtil::isHorizontalWhitespace(*start))
+ start++;
+ while (end > start && CharUtil::isHorizontalWhitespace(end[-1]))
+ end--;
+ return UnownedStringSlice(start, end);
+}
- while (start < m_end && CharUtil::isHorizontalWhitespace(*start)) start++;
- return UnownedStringSlice(start, m_end);
- }
+UnownedStringSlice UnownedStringSlice::trimStart() const
+{
+ const char* start = m_begin;
- UnownedStringSlice UnownedStringSlice::trim(char c) const
- {
- const char* start = m_begin;
- const char* end = m_end;
+ while (start < m_end && CharUtil::isHorizontalWhitespace(*start))
+ start++;
+ return UnownedStringSlice(start, m_end);
+}
- while (start < end && *start == c) start++;
- while (end > start && end[-1] == c) end--;
- return UnownedStringSlice(start, end);
- }
+UnownedStringSlice UnownedStringSlice::trim(char c) const
+{
+ const char* start = m_begin;
+ const char* end = m_end;
+
+ while (start < end && *start == c)
+ start++;
+ while (end > start && end[-1] == c)
+ end--;
+ return UnownedStringSlice(start, end);
+}
- // StringSlice
+// StringSlice
- StringSlice::StringSlice()
- : representation(0)
- , beginIndex(0)
- , endIndex(0)
- {}
+StringSlice::StringSlice()
+ : representation(0), beginIndex(0), endIndex(0)
+{
+}
- StringSlice::StringSlice(String const& str)
- : representation(str.m_buffer)
- , beginIndex(0)
- , endIndex(str.getLength())
- {}
+StringSlice::StringSlice(String const& str)
+ : representation(str.m_buffer), beginIndex(0), endIndex(str.getLength())
+{
+}
- StringSlice::StringSlice(String const& str, UInt beginIndex, UInt endIndex)
- : representation(str.m_buffer)
- , beginIndex(beginIndex)
- , endIndex(endIndex)
- {}
+StringSlice::StringSlice(String const& str, UInt beginIndex, UInt endIndex)
+ : representation(str.m_buffer), beginIndex(beginIndex), endIndex(endIndex)
+{
+}
- //
+//
- _EndLine EndLine;
+_EndLine EndLine;
- String operator+(const char * op1, const String & op2)
- {
- String result(op1);
- result.append(op2);
- return result;
- }
+String operator+(const char* op1, const String& op2)
+{
+ String result(op1);
+ result.append(op2);
+ return result;
+}
- String operator+(const String & op1, const char * op2)
- {
- String result(op1);
- result.append(op2);
- return result;
- }
+String operator+(const String& op1, const char* op2)
+{
+ String result(op1);
+ result.append(op2);
+ return result;
+}
- String operator+(const String & op1, const String & op2)
- {
- String result(op1);
- result.append(op2);
- return result;
- }
+String operator+(const String& op1, const String& op2)
+{
+ String result(op1);
+ result.append(op2);
+ return result;
+}
- int stringToInt(const String& str, int radix)
- {
- if (str.startsWith("0x"))
- return (int)strtoll(str.getBuffer(), NULL, 16);
- else
- return (int)strtoll(str.getBuffer(), NULL, radix);
- }
- unsigned int stringToUInt(const String& str, int radix)
- {
- if (str.startsWith("0x"))
- return (unsigned int)strtoull(str.getBuffer(), NULL, 16);
- else
- return (unsigned int)strtoull(str.getBuffer(), NULL, radix);
- }
- double stringToDouble(const String& str)
- {
- return (double)strtod(str.getBuffer(), NULL);
- }
- float stringToFloat(const String& str)
- {
- return strtof(str.getBuffer(), NULL);
- }
+int stringToInt(const String& str, int radix)
+{
+ if (str.startsWith("0x"))
+ return (int)strtoll(str.getBuffer(), NULL, 16);
+ else
+ return (int)strtoll(str.getBuffer(), NULL, radix);
+}
+unsigned int stringToUInt(const String& str, int radix)
+{
+ if (str.startsWith("0x"))
+ return (unsigned int)strtoull(str.getBuffer(), NULL, 16);
+ else
+ return (unsigned int)strtoull(str.getBuffer(), NULL, radix);
+}
+double stringToDouble(const String& str)
+{
+ return (double)strtod(str.getBuffer(), NULL);
+}
+float stringToFloat(const String& str)
+{
+ return strtof(str.getBuffer(), NULL);
+}
#if 0
String String::ReplaceAll(String src, String dst) const
@@ -300,446 +304,473 @@ namespace Slang
}
#endif
- String String::fromWString(const wchar_t* wstr)
- {
- List<char> buf;
+String String::fromWString(const wchar_t* wstr)
+{
+ List<char> buf;
#ifdef _WIN32
- Slang::CharEncoding::UTF16->decode((const Byte*)wstr, (int)(wcslen(wstr) * sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF16->decode(
+ (const Byte*)wstr,
+ (int)(wcslen(wstr) * sizeof(wchar_t)),
+ buf);
#else
- Slang::CharEncoding::UTF32->decode((const Byte*)wstr, (int)(wcslen(wstr) * sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF32->decode(
+ (const Byte*)wstr,
+ (int)(wcslen(wstr) * sizeof(wchar_t)),
+ buf);
#endif
- return String(buf.begin(), buf.end());
- }
+ return String(buf.begin(), buf.end());
+}
- String String::fromWString(const wchar_t* wstr, const wchar_t* wend)
- {
- List<char> buf;
+String String::fromWString(const wchar_t* wstr, const wchar_t* wend)
+{
+ List<char> buf;
#ifdef _WIN32
- Slang::CharEncoding::UTF16->decode((const Byte*)wstr, (int)((wend - wstr) * sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF16->decode(
+ (const Byte*)wstr,
+ (int)((wend - wstr) * sizeof(wchar_t)),
+ buf);
#else
- Slang::CharEncoding::UTF32->decode((const Byte*)wstr, (int)((wend - wstr) * sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF32->decode(
+ (const Byte*)wstr,
+ (int)((wend - wstr) * sizeof(wchar_t)),
+ buf);
#endif
- return String(buf.begin(), buf.end());
- }
+ return String(buf.begin(), buf.end());
+}
- String String::fromWChar(const wchar_t ch)
- {
- List<char> buf;
+String String::fromWChar(const wchar_t ch)
+{
+ List<char> buf;
#ifdef _WIN32
- Slang::CharEncoding::UTF16->decode((const Byte*)&ch, (int)(sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF16->decode((const Byte*)&ch, (int)(sizeof(wchar_t)), buf);
#else
- Slang::CharEncoding::UTF32->decode((const Byte*)&ch, (int)(sizeof(wchar_t)), buf);
+ Slang::CharEncoding::UTF32->decode((const Byte*)&ch, (int)(sizeof(wchar_t)), buf);
#endif
- return String(buf.begin(), buf.end());
- }
+ return String(buf.begin(), buf.end());
+}
+
+/* static */ String String::fromUnicodePoint(Char32 codePoint)
+{
+ char buf[6];
+ int len = Slang::encodeUnicodePointToUTF8(codePoint, buf);
+ return String(buf, buf + len);
+}
- /* static */String String::fromUnicodePoint(Char32 codePoint)
+OSString String::toWString(Index* outLength) const
+{
+ if (!m_buffer)
{
- char buf[6];
- int len = Slang::encodeUnicodePointToUTF8(codePoint, buf);
- return String(buf, buf + len);
+ return OSString();
}
-
- OSString String::toWString(Index* outLength) const
+ else
{
- if (!m_buffer)
+ List<Byte> buf;
+ switch (sizeof(wchar_t))
{
- return OSString();
- }
- else
- {
- List<Byte> buf;
- switch(sizeof(wchar_t))
- {
- case 2:
- Slang::CharEncoding::UTF16->encode(getUnownedSlice(), buf);
- break;
+ case 2: Slang::CharEncoding::UTF16->encode(getUnownedSlice(), buf); break;
- case 4:
- Slang::CharEncoding::UTF32->encode(getUnownedSlice(), buf);
- break;
+ case 4: Slang::CharEncoding::UTF32->encode(getUnownedSlice(), buf); break;
- default:
- break;
- }
+ default: break;
+ }
- auto length = Index(buf.getCount() / sizeof(wchar_t));
- if (outLength)
- *outLength = length;
+ auto length = Index(buf.getCount() / sizeof(wchar_t));
+ if (outLength)
+ *outLength = length;
- for(size_t ii = 0; ii < sizeof(wchar_t); ++ii)
- buf.add(0);
+ for (size_t ii = 0; ii < sizeof(wchar_t); ++ii)
+ buf.add(0);
- wchar_t* beginData = (wchar_t*)buf.getBuffer();
- wchar_t* endData = beginData + length;
+ wchar_t* beginData = (wchar_t*)buf.getBuffer();
+ wchar_t* endData = beginData + length;
- OSString ret;
- ret.set(beginData, endData);
- return ret;
- }
+ OSString ret;
+ ret.set(beginData, endData);
+ return ret;
}
+}
+
+//
- //
+void String::ensureUniqueStorageWithCapacity(Index requiredCapacity)
+{
+ if (m_buffer && m_buffer->isUniquelyReferenced() && m_buffer->capacity >= requiredCapacity)
+ return;
- void String::ensureUniqueStorageWithCapacity(Index requiredCapacity)
+ Index newCapacity = m_buffer ? 2 * m_buffer->capacity : 16;
+ if (newCapacity < requiredCapacity)
{
- if (m_buffer && m_buffer->isUniquelyReferenced() && m_buffer->capacity >= requiredCapacity)
- return;
+ newCapacity = requiredCapacity;
+ }
- Index newCapacity = m_buffer ? 2 * m_buffer->capacity : 16;
- if (newCapacity < requiredCapacity)
- {
- newCapacity = requiredCapacity;
- }
+ Index length = getLength();
+ StringRepresentation* newRepresentation =
+ StringRepresentation::createWithCapacityAndLength(newCapacity, length);
- Index length = getLength();
- StringRepresentation* newRepresentation = StringRepresentation::createWithCapacityAndLength(newCapacity, length);
+ if (m_buffer)
+ {
+ memcpy(newRepresentation->getData(), m_buffer->getData(), length + 1);
+ }
- if (m_buffer)
- {
- memcpy(newRepresentation->getData(), m_buffer->getData(), length + 1);
- }
+ m_buffer = newRepresentation;
+}
- m_buffer = newRepresentation;
- }
+char* String::prepareForAppend(Index count)
+{
+ auto oldLength = getLength();
+ auto newLength = oldLength + count;
+ ensureUniqueStorageWithCapacity(newLength);
+ return getData() + oldLength;
+}
+void String::appendInPlace(const char* chars, Index count)
+{
+ SLANG_UNUSED(chars);
- char* String::prepareForAppend(Index count)
+ if (count > 0)
{
+ SLANG_ASSERT(m_buffer && m_buffer->isUniquelyReferenced());
+
auto oldLength = getLength();
auto newLength = oldLength + count;
- ensureUniqueStorageWithCapacity(newLength);
- return getData() + oldLength;
- }
- void String::appendInPlace(const char* chars, Index count)
- {
- SLANG_UNUSED(chars);
-
- if (count > 0)
- {
- SLANG_ASSERT(m_buffer && m_buffer->isUniquelyReferenced());
-
- auto oldLength = getLength();
- auto newLength = oldLength + count;
- char* dst = m_buffer->getData();
+ char* dst = m_buffer->getData();
- // Make sure the input buffer is the same one returned from prepareForAppend
- SLANG_ASSERT(chars == dst + oldLength);
- // It has to fit within the capacity
- SLANG_ASSERT(newLength <= m_buffer->capacity);
+ // Make sure the input buffer is the same one returned from prepareForAppend
+ SLANG_ASSERT(chars == dst + oldLength);
+ // It has to fit within the capacity
+ SLANG_ASSERT(newLength <= m_buffer->capacity);
- // We just need to modify the length
- m_buffer->length = newLength;
+ // We just need to modify the length
+ m_buffer->length = newLength;
- // And mark with a terminating 0
- dst[newLength] = 0;
- }
+ // And mark with a terminating 0
+ dst[newLength] = 0;
}
+}
- void String::reduceLength(Index newLength)
+void String::reduceLength(Index newLength)
+{
+ Index oldLength = getLength();
+ SLANG_ASSERT(newLength <= oldLength);
+ if (oldLength == newLength)
{
- Index oldLength = getLength();
- SLANG_ASSERT(newLength <= oldLength);
- if (oldLength == newLength)
- {
- return;
- }
+ return;
+ }
- // It must have a buffer, because only 0 length allows for nullptr
- // and being 0 sized is already covered
- SLANG_ASSERT(m_buffer);
+ // It must have a buffer, because only 0 length allows for nullptr
+ // and being 0 sized is already covered
+ SLANG_ASSERT(m_buffer);
- if (m_buffer->isUniquelyReferenced())
+ if (m_buffer->isUniquelyReferenced())
+ {
+ m_buffer->length = newLength;
+ m_buffer->getData()[newLength] = 0;
+ }
+ else
+ {
+ // If 0 length is wanted we can just free
+ if (newLength == 0)
{
- m_buffer->length = newLength;
- m_buffer->getData()[newLength] = 0;
+ m_buffer.setNull();
}
else
{
- // If 0 length is wanted we can just free
- if (newLength == 0)
- {
- m_buffer.setNull();
- }
- else
- {
- // We need to make a new copy, that we will shrink
+ // We need to make a new copy, that we will shrink
- // We'll just go with capacity enough for the new length
- const Index newCapacity = newLength;
- StringRepresentation* newRepresentation = StringRepresentation::createWithCapacityAndLength(newCapacity, newLength);
+ // We'll just go with capacity enough for the new length
+ const Index newCapacity = newLength;
+ StringRepresentation* newRepresentation =
+ StringRepresentation::createWithCapacityAndLength(newCapacity, newLength);
- // Copy
- char* dst = newRepresentation->getData();
- memcpy(dst, m_buffer->getData(), sizeof(char) * newLength);
- // Zero terminate
- dst[newLength] = 0;
+ // Copy
+ char* dst = newRepresentation->getData();
+ memcpy(dst, m_buffer->getData(), sizeof(char) * newLength);
+ // Zero terminate
+ dst[newLength] = 0;
- // Set the new rep
- m_buffer = newRepresentation;
- }
+ // Set the new rep
+ m_buffer = newRepresentation;
}
}
+}
- void String::append(char const* str, size_t len)
- {
- append(str, str + len);
- }
+void String::append(char const* str, size_t len)
+{
+ append(str, str + len);
+}
- void String::append(const char* textBegin, char const* textEnd)
- {
- auto oldLength = getLength();
- auto textLength = textEnd - textBegin;
- if (textLength <= 0)
- return;
+void String::append(const char* textBegin, char const* textEnd)
+{
+ auto oldLength = getLength();
+ auto textLength = textEnd - textBegin;
+ if (textLength <= 0)
+ return;
- auto newLength = oldLength + textLength;
+ auto newLength = oldLength + textLength;
- ensureUniqueStorageWithCapacity(newLength);
+ ensureUniqueStorageWithCapacity(newLength);
- memcpy(getData() + oldLength, textBegin, textLength);
- getData()[newLength] = 0;
- m_buffer->length = newLength;
- }
+ memcpy(getData() + oldLength, textBegin, textLength);
+ getData()[newLength] = 0;
+ m_buffer->length = newLength;
+}
- void String::append(char const* str)
+void String::append(char const* str)
+{
+ if (str)
{
- if (str)
- {
- append(str, str + strlen(str));
- }
+ append(str, str + strlen(str));
}
+}
- void String::appendRepeatedChar(char chr, Index count)
+void String::appendRepeatedChar(char chr, Index count)
+{
+ SLANG_ASSERT(count >= 0);
+ if (count > 0)
{
- SLANG_ASSERT(count >= 0);
- if (count > 0)
- {
- char* chars = prepareForAppend(count);
- // Set all space to repeated chr.
- ::memset(chars, chr, sizeof(char) * count);
- appendInPlace(chars, count);
- }
+ char* chars = prepareForAppend(count);
+ // Set all space to repeated chr.
+ ::memset(chars, chr, sizeof(char) * count);
+ appendInPlace(chars, count);
}
+}
- void String::appendChar(char c)
- {
- const auto oldLength = getLength();
- const auto newLength = oldLength + 1;
+void String::appendChar(char c)
+{
+ const auto oldLength = getLength();
+ const auto newLength = oldLength + 1;
- ensureUniqueStorageWithCapacity(newLength);
+ ensureUniqueStorageWithCapacity(newLength);
- // Since there must be space for at least one character, m_buffer cannot be nullptr
- SLANG_ASSERT(m_buffer);
- char* data = m_buffer->getData();
- data[oldLength] = c;
- data[newLength] = 0;
+ // Since there must be space for at least one character, m_buffer cannot be nullptr
+ SLANG_ASSERT(m_buffer);
+ char* data = m_buffer->getData();
+ data[oldLength] = c;
+ data[newLength] = 0;
- m_buffer->length = newLength;
- }
+ m_buffer->length = newLength;
+}
- void String::append(char chr)
+void String::append(char chr)
+{
+ appendChar(chr);
+}
+
+void String::append(String const& str)
+{
+ if (!m_buffer)
{
- appendChar(chr);
+ m_buffer = str.m_buffer;
+ return;
}
- void String::append(String const& str)
- {
- if (!m_buffer)
- {
- m_buffer = str.m_buffer;
- return;
- }
+ append(str.begin(), str.end());
+}
- append(str.begin(), str.end());
- }
+void String::append(StringSlice const& slice)
+{
+ append(slice.begin(), slice.end());
+}
- void String::append(StringSlice const& slice)
- {
- append(slice.begin(), slice.end());
- }
+void String::append(UnownedStringSlice const& slice)
+{
+ append(slice.begin(), slice.end());
+}
- void String::append(UnownedStringSlice const& slice)
+void String::append(int32_t value, int radix)
+{
+ enum
{
- append(slice.begin(), slice.end());
- }
+ kCount = 33
+ };
+ char* data = prepareForAppend(kCount);
+ const auto count = intToAscii(data, value, radix);
+ m_buffer->length += count;
+}
- void String::append(int32_t value, int radix)
+void String::append(uint32_t value, int radix)
+{
+ enum
{
- enum { kCount = 33 };
- char* data = prepareForAppend(kCount);
- const auto count = intToAscii(data, value, radix);
- m_buffer->length += count;
- }
+ kCount = 33
+ };
+ char* data = prepareForAppend(kCount);
+ const auto count = intToAscii(data, value, radix);
+ m_buffer->length += count;
+}
- void String::append(uint32_t value, int radix)
+void String::append(int64_t value, int radix)
+{
+ enum
{
- enum { kCount = 33 };
- char* data = prepareForAppend(kCount);
- const auto count = intToAscii(data, value, radix);
- m_buffer->length += count;
- }
+ kCount = 65
+ };
+ char* data = prepareForAppend(kCount);
+ auto count = intToAscii(data, value, radix);
+ m_buffer->length += count;
+}
- void String::append(int64_t value, int radix)
+void String::append(uint64_t value, int radix)
+{
+ enum
{
- enum { kCount = 65 };
- char* data = prepareForAppend(kCount);
- auto count = intToAscii(data, value, radix);
- m_buffer->length += count;
- }
+ kCount = 65
+ };
+ char* data = prepareForAppend(kCount);
+ auto count = intToAscii(data, value, radix);
+ m_buffer->length += count;
+}
- void String::append(uint64_t value, int radix)
+void String::append(float val, const char* format)
+{
+ enum
{
- enum { kCount = 65 };
- char* data = prepareForAppend(kCount);
- auto count = intToAscii(data, value, radix);
- m_buffer->length += count;
- }
+ kCount = 128
+ };
+ char* data = prepareForAppend(kCount);
+ sprintf_s(data, kCount, format, val);
+ m_buffer->length += strnlen_s(data, kCount);
+}
- void String::append(float val, const char* format)
+void String::append(double val, const char* format)
+{
+ enum
{
- enum { kCount = 128 };
- char* data = prepareForAppend(kCount);
- sprintf_s(data, kCount, format, val);
- m_buffer->length += strnlen_s(data, kCount);
- }
+ kCount = 128
+ };
+ char* data = prepareForAppend(kCount);
+ sprintf_s(data, kCount, format, val);
+ m_buffer->length += strnlen_s(data, kCount);
+}
+
+void String::append(StableHashCode32 value)
+{
+ const Index digits = 8;
+ // + null terminator
+ char* data = prepareForAppend(digits + 1);
+ auto count = intToAscii(data, value.hash, 16, digits);
+ m_buffer->length += count;
+}
- void String::append(double val, const char* format)
+void String::append(StableHashCode64 value)
+{
+ const Index digits = 16;
+ // + null terminator
+ char* data = prepareForAppend(digits + 1);
+ auto count = intToAscii(data, value.hash, 16, digits);
+ m_buffer->length += count;
+}
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UnownedStringSlice !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+Index UnownedStringSlice::indexOf(char c) const
+{
+ const Index size = Index(m_end - m_begin);
+ for (Index i = 0; i < size; ++i)
{
- enum { kCount = 128 };
- char* data = prepareForAppend(kCount);
- sprintf_s(data, kCount, format, val);
- m_buffer->length += strnlen_s(data, kCount);
+ if (m_begin[i] == c)
+ {
+ return i;
+ }
}
+ return -1;
+}
- void String::append(StableHashCode32 value)
+Index UnownedStringSlice::indexOf(const UnownedStringSlice& in) const
+{
+ const Index len = getLength();
+ const Index inLen = in.getLength();
+ if (inLen > len)
{
- const Index digits = 8;
- // + null terminator
- char* data = prepareForAppend(digits + 1);
- auto count = intToAscii(data, value.hash, 16, digits);
- m_buffer->length += count;
+ return -1;
}
- void String::append(StableHashCode64 value)
+ const char* inChars = in.m_begin;
+ switch (inLen)
{
- const Index digits = 16;
- // + null terminator
- char* data = prepareForAppend(digits + 1);
- auto count = intToAscii(data, value.hash, 16, digits);
- m_buffer->length += count;
+ case 0: return 0;
+ case 1: return indexOf(inChars[0]);
+ default: break;
}
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UnownedStringSlice !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ const char* chars = m_begin;
+ const char firstChar = inChars[0];
- Index UnownedStringSlice::indexOf(char c) const
+ for (Int i = 0; i <= len - inLen; ++i)
{
- const Index size = Index(m_end - m_begin);
- for (Index i = 0; i < size; ++i)
+ if (chars[i] == firstChar && in == UnownedStringSlice(chars + i, inLen))
{
- if (m_begin[i] == c)
- {
- return i;
- }
+ return i;
}
- return -1;
}
- Index UnownedStringSlice::indexOf(const UnownedStringSlice& in) const
- {
- const Index len = getLength();
- const Index inLen = in.getLength();
- if (inLen > len)
- {
- return -1;
- }
+ return -1;
+}
- const char* inChars = in.m_begin;
- switch (inLen)
- {
- case 0: return 0;
- case 1: return indexOf(inChars[0]);
- default: break;
- }
+UnownedStringSlice UnownedStringSlice::subString(Index idx, Index len) const
+{
+ const Index totalLen = getLength();
+ SLANG_ASSERT(idx >= 0 && len >= 0 && idx <= totalLen);
- const char* chars = m_begin;
- const char firstChar = inChars[0];
+ // If too large, we truncate
+ len = (idx + len > totalLen) ? (totalLen - idx) : len;
- for (Int i = 0; i <= len - inLen; ++i)
- {
- if (chars[i] == firstChar && in == UnownedStringSlice(chars + i, inLen))
- {
- return i;
- }
- }
+ // Return the substring
+ return UnownedStringSlice(m_begin + idx, m_begin + idx + len);
+}
- return -1;
- }
+bool UnownedStringSlice::operator==(ThisType const& other) const
+{
+ // Note that memcmp is undefined when passed in null ptrs, so if we want to handle
+ // we need to cover that case.
+ // Can only be nullptr if size is 0.
+ auto thisSize = getLength();
+ auto otherSize = other.getLength();
- UnownedStringSlice UnownedStringSlice::subString(Index idx, Index len) const
+ if (thisSize != otherSize)
{
- const Index totalLen = getLength();
- SLANG_ASSERT(idx >= 0 && len >= 0 && idx <= totalLen);
-
- // If too large, we truncate
- len = (idx + len > totalLen) ? (totalLen - idx) : len;
-
- // Return the substring
- return UnownedStringSlice(m_begin + idx, m_begin + idx + len);
+ return false;
}
- bool UnownedStringSlice::operator==(ThisType const& other) const
+ const char* const thisChars = begin();
+ const char* const otherChars = other.begin();
+ if (thisChars == otherChars || thisSize == 0)
{
- // Note that memcmp is undefined when passed in null ptrs, so if we want to handle
- // we need to cover that case.
- // Can only be nullptr if size is 0.
- auto thisSize = getLength();
- auto otherSize = other.getLength();
-
- if (thisSize != otherSize)
- {
- return false;
- }
-
- const char*const thisChars = begin();
- const char*const otherChars = other.begin();
- if (thisChars == otherChars || thisSize == 0)
- {
- return true;
- }
- SLANG_ASSERT(thisChars && otherChars);
- return memcmp(thisChars, otherChars, thisSize) == 0;
+ return true;
}
+ SLANG_ASSERT(thisChars && otherChars);
+ return memcmp(thisChars, otherChars, thisSize) == 0;
+}
- bool UnownedStringSlice::caseInsensitiveEquals(const ThisType& rhs) const
+bool UnownedStringSlice::caseInsensitiveEquals(const ThisType& rhs) const
+{
+ const auto length = getLength();
+ if (length != rhs.getLength())
{
- const auto length = getLength();
- if (length != rhs.getLength())
- {
- return false;
- }
+ return false;
+ }
- const char* a = m_begin;
- const char* b = rhs.m_begin;
+ const char* a = m_begin;
+ const char* b = rhs.m_begin;
- // Assuming this is a faster test
- if (memcmp(a, b, length) != 0)
+ // Assuming this is a faster test
+ if (memcmp(a, b, length) != 0)
+ {
+ // They aren't identical so compare character by character
+ for (Index i = 0; i < length; ++i)
{
- // They aren't identical so compare character by character
- for (Index i = 0; i < length; ++i)
+ if (CharUtil::toLower(a[i]) != CharUtil::toLower(b[i]))
{
- if (CharUtil::toLower(a[i]) != CharUtil::toLower(b[i]))
- {
- return false;
- }
+ return false;
}
}
-
- return true;
}
+
+ return true;
}
+} // namespace Slang
-std::ostream& operator<< (std::ostream& stream, const Slang::String& s)
+std::ostream& operator<<(std::ostream& stream, const Slang::String& s)
{
stream << s.getBuffer();
return stream;
diff --git a/source/core/slang-string.h b/source/core/slang-string.h
index 6c0dec420..24b119383 100644
--- a/source/core/slang-string.h
+++ b/source/core/slang-string.h
@@ -1,989 +1,872 @@
#ifndef SLANG_CORE_STRING_H
#define SLANG_CORE_STRING_H
-#include <string.h>
-#include <cstdlib>
-#include <stdio.h>
-#include <iostream>
-
-#include "slang-smart-pointer.h"
#include "slang-common.h"
#include "slang-hash.h"
#include "slang-secure-crt.h"
+#include "slang-smart-pointer.h"
#include "slang-stable-hash.h"
+#include <cstdlib>
+#include <iostream>
#include <new>
+#include <stdio.h>
+#include <string.h>
#include <type_traits>
namespace Slang
{
- class _EndLine
- {};
- extern _EndLine EndLine;
+class _EndLine
+{
+};
+extern _EndLine EndLine;
- // in-place reversion, works only for ascii string
- inline void reverseInplaceAscii(char* buffer, int length)
+// in-place reversion, works only for ascii string
+inline void reverseInplaceAscii(char* buffer, int length)
+{
+ int i, j;
+ char c;
+ for (i = 0, j = length - 1; i < j; i++, j--)
{
- int i, j;
- char c;
- for (i = 0, j = length - 1; i<j; i++, j--)
- {
- c = buffer[i];
- buffer[i] = buffer[j];
- buffer[j] = c;
- }
+ c = buffer[i];
+ buffer[i] = buffer[j];
+ buffer[j] = c;
}
- template<typename IntType>
- inline int intToAscii(char* buffer, IntType val, int radix, int padTo = 0)
+}
+template<typename IntType>
+inline int intToAscii(char* buffer, IntType val, int radix, int padTo = 0)
+{
+ static_assert(std::is_integral_v<IntType>);
+
+ int i = 0;
+ IntType sign;
+
+ sign = val;
+ if (sign < 0)
{
- static_assert(std::is_integral_v<IntType>);
+ val = (IntType)(0 - val);
+ }
- int i = 0;
- IntType sign;
-
- sign = val;
- if (sign < 0)
- {
- val = (IntType)(0 - val);
- }
+ do
+ {
+ int digit = (val % radix);
+ if (digit <= 9)
+ buffer[i++] = (char)(digit + '0');
+ else
+ buffer[i++] = (char)(digit - 10 + 'A');
+ } while ((val /= radix) > 0);
- do
- {
- int digit = (val % radix);
- if (digit <= 9)
- buffer[i++] = (char)(digit + '0');
- else
- buffer[i++] = (char)(digit - 10 + 'A');
- } while ((val /= radix) > 0);
+ SLANG_ASSERT(i >= 0);
+ while (i < padTo)
+ buffer[i++] = '0';
- SLANG_ASSERT(i >= 0);
- while(i < padTo)
- buffer[i++] = '0';
+ if (sign < 0)
+ buffer[i++] = '-';
- if (sign < 0)
- buffer[i++] = '-';
+ // Put in normal character order
+ reverseInplaceAscii(buffer, i);
- // Put in normal character order
- reverseInplaceAscii(buffer, i);
+ buffer[i] = '\0';
+ return i;
+}
- buffer[i] = '\0';
- return i;
- }
+SLANG_FORCE_INLINE bool isUtf8LeadingByte(char ch)
+{
+ return (((unsigned char)ch) & 0xC0) == 0xC0;
+}
+
+SLANG_FORCE_INLINE bool isUtf8ContinuationByte(char ch)
+{
+ return (((unsigned char)ch) & 0xC0) == 0x80;
+}
- SLANG_FORCE_INLINE bool isUtf8LeadingByte(char ch)
+/* A string slice that doesn't own the contained characters.
+It is the responsibility of code using the type to keep the memory backing
+the slice in scope.
+A slice is generally *not* zero terminated. */
+struct SLANG_RT_API UnownedStringSlice
+{
+public:
+ typedef UnownedStringSlice ThisType;
+
+ // Type to indicate that a ctor is with a length to disabmiguate 0/nullptr
+ // causing ambiguity.
+ struct WithLength
{
- return (((unsigned char)ch) & 0xC0) == 0xC0;
- }
+ };
- SLANG_FORCE_INLINE bool isUtf8ContinuationByte(char ch)
+ UnownedStringSlice()
+ : m_begin(nullptr), m_end(nullptr)
{
- return (((unsigned char)ch) & 0xC0) == 0x80;
}
- /* A string slice that doesn't own the contained characters.
- It is the responsibility of code using the type to keep the memory backing
- the slice in scope.
- A slice is generally *not* zero terminated. */
- struct SLANG_RT_API UnownedStringSlice
+ explicit UnownedStringSlice(char const* a)
+ : m_begin(a), m_end(a ? a + strlen(a) : nullptr)
{
- public:
- typedef UnownedStringSlice ThisType;
-
- // Type to indicate that a ctor is with a length to disabmiguate 0/nullptr
- // causing ambiguity.
- struct WithLength {};
-
- UnownedStringSlice()
- : m_begin(nullptr)
- , m_end(nullptr)
- {}
-
- explicit UnownedStringSlice(char const* a) :
- m_begin(a),
- m_end(a ? a + strlen(a) : nullptr)
- {}
- UnownedStringSlice(char const* b, char const* e)
- : m_begin(b)
- , m_end(e)
- {}
- UnownedStringSlice(char const* b, size_t len)
- : m_begin(b)
- , m_end(b + len)
- {}
- UnownedStringSlice(WithLength, char const* b, size_t len)
- : m_begin(b)
- , m_end(b + len)
- {}
+ }
+ UnownedStringSlice(char const* b, char const* e)
+ : m_begin(b), m_end(e)
+ {
+ }
+ UnownedStringSlice(char const* b, size_t len)
+ : m_begin(b), m_end(b + len)
+ {
+ }
+ UnownedStringSlice(WithLength, char const* b, size_t len)
+ : m_begin(b), m_end(b + len)
+ {
+ }
- SLANG_FORCE_INLINE char const* begin() const { return m_begin; }
+ SLANG_FORCE_INLINE char const* begin() const { return m_begin; }
- SLANG_FORCE_INLINE char const* end() const { return m_end; }
+ SLANG_FORCE_INLINE char const* end() const { return m_end; }
- /// True if slice is strictly contained in memory.
- bool isMemoryContained(const UnownedStringSlice& slice) const
- {
- return slice.m_begin >= m_begin && slice.m_end <= m_end;
- }
- bool isMemoryContained(const char* pos) const
- {
- return pos >= m_begin && pos <= m_end;
- }
+ /// True if slice is strictly contained in memory.
+ bool isMemoryContained(const UnownedStringSlice& slice) const
+ {
+ return slice.m_begin >= m_begin && slice.m_end <= m_end;
+ }
+ bool isMemoryContained(const char* pos) const { return pos >= m_begin && pos <= m_end; }
- /// Get the length in *bytes*
- Count getLength() const { return Index(m_end - m_begin); }
+ /// Get the length in *bytes*
+ Count getLength() const { return Index(m_end - m_begin); }
- /// Finds first index of char 'c'. If not found returns -1.
- Index indexOf(char c) const;
- /// Find first index of slice. If not found returns -1
- Index indexOf(const UnownedStringSlice& slice) const;
+ /// Finds first index of char 'c'. If not found returns -1.
+ Index indexOf(char c) const;
+ /// Find first index of slice. If not found returns -1
+ Index indexOf(const UnownedStringSlice& slice) const;
- /// Returns a substring. idx is the start index, and len
- /// is the amount of characters.
- /// The returned length might be truncated, if len extends beyond slice.
- UnownedStringSlice subString(Index idx, Index len) const;
+ /// Returns a substring. idx is the start index, and len
+ /// is the amount of characters.
+ /// The returned length might be truncated, if len extends beyond slice.
+ UnownedStringSlice subString(Index idx, Index len) const;
- /// Return a head of the slice - everything up to the index
- SLANG_FORCE_INLINE UnownedStringSlice head(Index idx) const { SLANG_ASSERT(idx >= 0 && idx <= getLength()); return UnownedStringSlice(m_begin, idx); }
- /// Return a tail of the slice - everything from the index to the end of the slice
- SLANG_FORCE_INLINE UnownedStringSlice tail(Index idx) const { SLANG_ASSERT(idx >= 0 && idx <= getLength()); return UnownedStringSlice(m_begin + idx, m_end); }
+ /// Return a head of the slice - everything up to the index
+ SLANG_FORCE_INLINE UnownedStringSlice head(Index idx) const
+ {
+ SLANG_ASSERT(idx >= 0 && idx <= getLength());
+ return UnownedStringSlice(m_begin, idx);
+ }
+ /// Return a tail of the slice - everything from the index to the end of the slice
+ SLANG_FORCE_INLINE UnownedStringSlice tail(Index idx) const
+ {
+ SLANG_ASSERT(idx >= 0 && idx <= getLength());
+ return UnownedStringSlice(m_begin + idx, m_end);
+ }
- /// True if rhs and this are equal without having to take into account case
- /// Note 'case' here is *not* locale specific - it is only A-Z and a-z
- bool caseInsensitiveEquals(const ThisType& rhs) const;
+ /// True if rhs and this are equal without having to take into account case
+ /// Note 'case' here is *not* locale specific - it is only A-Z and a-z
+ bool caseInsensitiveEquals(const ThisType& rhs) const;
- Index lastIndexOf(char c) const
+ Index lastIndexOf(char c) const
+ {
+ const Index size = Index(m_end - m_begin);
+ for (Index i = size - 1; i >= 0; --i)
{
- const Index size = Index(m_end - m_begin);
- for (Index i = size - 1; i >= 0; --i)
+ if (m_begin[i] == c)
{
- if (m_begin[i] == c)
- {
- return i;
- }
+ return i;
}
- return -1;
}
+ return -1;
+ }
- const char& operator[](Index i) const
- {
- assert(i >= 0 && i < Index(m_end - m_begin));
- return m_begin[i];
- }
+ const char& operator[](Index i) const
+ {
+ assert(i >= 0 && i < Index(m_end - m_begin));
+ return m_begin[i];
+ }
- bool operator==(ThisType const& other) const;
- bool operator!=(UnownedStringSlice const& other) const { return !(*this == other); }
+ bool operator==(ThisType const& other) const;
+ bool operator!=(UnownedStringSlice const& other) const { return !(*this == other); }
- bool operator==(char const* str) const { return (*this) == UnownedStringSlice(str); }
- bool operator!=(char const* str) const { return !(*this == str); }
+ bool operator==(char const* str) const { return (*this) == UnownedStringSlice(str); }
+ bool operator!=(char const* str) const { return !(*this == str); }
- /// True if contents is a single char of c
- SLANG_FORCE_INLINE bool isChar(char c) const { return getLength() == 1 && m_begin[0] == c; }
+ /// True if contents is a single char of c
+ SLANG_FORCE_INLINE bool isChar(char c) const { return getLength() == 1 && m_begin[0] == c; }
- bool startsWithCaseInsensitive(UnownedStringSlice const& other) const;
- bool startsWith(UnownedStringSlice const& other) const;
- bool startsWith(char const* str) const;
+ bool startsWithCaseInsensitive(UnownedStringSlice const& other) const;
+ bool startsWith(UnownedStringSlice const& other) const;
+ bool startsWith(char const* str) const;
- bool endsWithCaseInsensitive(UnownedStringSlice const& other) const;
- bool endsWithCaseInsensitive(char const* str) const;
+ bool endsWithCaseInsensitive(UnownedStringSlice const& other) const;
+ bool endsWithCaseInsensitive(char const* str) const;
- bool endsWith(UnownedStringSlice const& other) const;
- bool endsWith(char const* str) const;
+ bool endsWith(UnownedStringSlice const& other) const;
+ bool endsWith(char const* str) const;
- /// Trims any horizontal whitespace from the start and end and returns as a substring
- UnownedStringSlice trim() const;
- /// Trims any 'c' from the start or the end, and returns as a substring
- UnownedStringSlice trim(char c) const;
+ /// Trims any horizontal whitespace from the start and end and returns as a substring
+ UnownedStringSlice trim() const;
+ /// Trims any 'c' from the start or the end, and returns as a substring
+ UnownedStringSlice trim(char c) const;
- /// Trims any horizonatl whitespace from start and returns as a substring
- UnownedStringSlice trimStart() const;
+ /// Trims any horizonatl whitespace from start and returns as a substring
+ UnownedStringSlice trimStart() const;
- static constexpr bool kHasUniformHash = true;
- HashCode64 getHashCode() const
- {
- return Slang::getHashCode(m_begin, size_t(m_end - m_begin));
- }
+ static constexpr bool kHasUniformHash = true;
+ HashCode64 getHashCode() const { return Slang::getHashCode(m_begin, size_t(m_end - m_begin)); }
- template <size_t SIZE>
- SLANG_FORCE_INLINE static UnownedStringSlice fromLiteral(const char (&in)[SIZE]) { return UnownedStringSlice(in, SIZE - 1); }
+ template<size_t SIZE>
+ SLANG_FORCE_INLINE static UnownedStringSlice fromLiteral(const char (&in)[SIZE])
+ {
+ return UnownedStringSlice(in, SIZE - 1);
+ }
- protected:
+protected:
+ char const* m_begin;
+ char const* m_end;
+};
- char const* m_begin;
- char const* m_end;
- };
+// A more convenient way to make slices from *string literals*
+template<size_t SIZE>
+SLANG_FORCE_INLINE UnownedStringSlice toSlice(const char (&in)[SIZE])
+{
+ return UnownedStringSlice(in, SIZE - 1);
+}
- // A more convenient way to make slices from *string literals*
- template <size_t SIZE>
- SLANG_FORCE_INLINE UnownedStringSlice toSlice(const char (&in)[SIZE]) { return UnownedStringSlice(in, SIZE - 1); }
-
- /// Same as UnownedStringSlice, but must be zero terminated.
- /// Zero termination is *not* included in the length.
- struct SLANG_RT_API UnownedTerminatedStringSlice : public UnownedStringSlice
- {
- public:
- typedef UnownedStringSlice Super;
- typedef UnownedTerminatedStringSlice ThisType;
-
- /// We can turn into a regular zero terminated string
- SLANG_FORCE_INLINE operator const char*() const { return m_begin; }
-
- /// Exists to match the equivalent function in String.
- SLANG_FORCE_INLINE char const* getBuffer() const { return m_begin; }
-
- /// Construct from a literal directly.
- template <size_t SIZE>
- SLANG_FORCE_INLINE static ThisType fromLiteral(const char(&in)[SIZE]) { return ThisType(in, SIZE - 1); }
-
- /// Default constructor
- UnownedTerminatedStringSlice():Super(Super::WithLength(), "", 0) {}
-
- /// Note, b cannot be null because if it were then the string would not be null terminated
- UnownedTerminatedStringSlice(char const* b)
- : Super(b, b + strlen(b))
- {}
- UnownedTerminatedStringSlice(char const* b, size_t len)
- : Super(b, len)
- {
- // b must be valid and it must be null terminated
- SLANG_ASSERT(b && b[len] == 0);
- }
- };
+/// Same as UnownedStringSlice, but must be zero terminated.
+/// Zero termination is *not* included in the length.
+struct SLANG_RT_API UnownedTerminatedStringSlice : public UnownedStringSlice
+{
+public:
+ typedef UnownedStringSlice Super;
+ typedef UnownedTerminatedStringSlice ThisType;
+
+ /// We can turn into a regular zero terminated string
+ SLANG_FORCE_INLINE operator const char*() const { return m_begin; }
- // A more convenient way to make terminated slices from *string literals*
- template <size_t SIZE>
- SLANG_FORCE_INLINE UnownedTerminatedStringSlice toTerminatedSlice(const char(&in)[SIZE]) { return UnownedTerminatedStringSlice(in, SIZE - 1); }
+ /// Exists to match the equivalent function in String.
+ SLANG_FORCE_INLINE char const* getBuffer() const { return m_begin; }
- // A `StringRepresentation` provides the backing storage for
- // all reference-counted string-related types.
- class SLANG_RT_API StringRepresentation : public RefObject
+ /// Construct from a literal directly.
+ template<size_t SIZE>
+ SLANG_FORCE_INLINE static ThisType fromLiteral(const char (&in)[SIZE])
{
- public:
- Index length;
- Index capacity;
+ return ThisType(in, SIZE - 1);
+ }
- SLANG_FORCE_INLINE Index getLength() const
- {
- return length;
- }
+ /// Default constructor
+ UnownedTerminatedStringSlice()
+ : Super(Super::WithLength(), "", 0)
+ {
+ }
- SLANG_FORCE_INLINE char* getData()
- {
- return (char*) (this + 1);
- }
- SLANG_FORCE_INLINE const char* getData() const
- {
- return (const char*)(this + 1);
- }
+ /// Note, b cannot be null because if it were then the string would not be null terminated
+ UnownedTerminatedStringSlice(char const* b)
+ : Super(b, b + strlen(b))
+ {
+ }
+ UnownedTerminatedStringSlice(char const* b, size_t len)
+ : Super(b, len)
+ {
+ // b must be valid and it must be null terminated
+ SLANG_ASSERT(b && b[len] == 0);
+ }
+};
- /// Set the contents to be the slice. Must be enough capacity to hold the slice.
- void setContents(const UnownedStringSlice& slice);
+// A more convenient way to make terminated slices from *string literals*
+template<size_t SIZE>
+SLANG_FORCE_INLINE UnownedTerminatedStringSlice toTerminatedSlice(const char (&in)[SIZE])
+{
+ return UnownedTerminatedStringSlice(in, SIZE - 1);
+}
- static const char* getData(const StringRepresentation* stringRep)
- {
- return stringRep ? stringRep->getData() : "";
- }
+// A `StringRepresentation` provides the backing storage for
+// all reference-counted string-related types.
+class SLANG_RT_API StringRepresentation : public RefObject
+{
+public:
+ Index length;
+ Index capacity;
- static UnownedStringSlice asSlice(const StringRepresentation* rep)
- {
- return rep ? UnownedStringSlice(rep->getData(), rep->getLength()) : UnownedStringSlice();
- }
+ SLANG_FORCE_INLINE Index getLength() const { return length; }
- static bool equal(const StringRepresentation* a, const StringRepresentation* b)
- {
- return (a == b) || asSlice(a) == asSlice(b);
- }
+ SLANG_FORCE_INLINE char* getData() { return (char*)(this + 1); }
+ SLANG_FORCE_INLINE const char* getData() const { return (const char*)(this + 1); }
- static StringRepresentation* createWithCapacityAndLength(Index capacity, Index length)
- {
- SLANG_ASSERT(capacity >= length);
- void* allocation = operator new(sizeof(StringRepresentation) + capacity + 1);
- StringRepresentation* obj = new(allocation) StringRepresentation();
- obj->capacity = capacity;
- obj->length = length;
- obj->getData()[length] = 0;
- return obj;
- }
+ /// Set the contents to be the slice. Must be enough capacity to hold the slice.
+ void setContents(const UnownedStringSlice& slice);
- static StringRepresentation* createWithCapacity(Index capacity)
- {
- return createWithCapacityAndLength(capacity, 0);
- }
+ static const char* getData(const StringRepresentation* stringRep)
+ {
+ return stringRep ? stringRep->getData() : "";
+ }
- static StringRepresentation* createWithLength(Index length)
- {
- return createWithCapacityAndLength(length, length);
- }
+ static UnownedStringSlice asSlice(const StringRepresentation* rep)
+ {
+ return rep ? UnownedStringSlice(rep->getData(), rep->getLength()) : UnownedStringSlice();
+ }
- /// Create a representation from the slice. If slice is empty will return nullptr.
- static StringRepresentation* create(const UnownedStringSlice& slice);
- /// Same as create, but representation will have refcount of 1 (if not nullptr)
- static StringRepresentation* createWithReference(const UnownedStringSlice& slice);
+ static bool equal(const StringRepresentation* a, const StringRepresentation* b)
+ {
+ return (a == b) || asSlice(a) == asSlice(b);
+ }
- StringRepresentation* cloneWithCapacity(Index newCapacity)
- {
- StringRepresentation* newObj = createWithCapacityAndLength(newCapacity, length);
- memcpy(getData(), newObj->getData(), length + 1);
- return newObj;
- }
+ static StringRepresentation* createWithCapacityAndLength(Index capacity, Index length)
+ {
+ SLANG_ASSERT(capacity >= length);
+ void* allocation = operator new(sizeof(StringRepresentation) + capacity + 1);
+ StringRepresentation* obj = new (allocation) StringRepresentation();
+ obj->capacity = capacity;
+ obj->length = length;
+ obj->getData()[length] = 0;
+ return obj;
+ }
- StringRepresentation* clone()
- {
- return cloneWithCapacity(length);
- }
+ static StringRepresentation* createWithCapacity(Index capacity)
+ {
+ return createWithCapacityAndLength(capacity, 0);
+ }
- StringRepresentation* ensureCapacity(Index required)
- {
- if (capacity >= required) return this;
+ static StringRepresentation* createWithLength(Index length)
+ {
+ return createWithCapacityAndLength(length, length);
+ }
- Index newCapacity = capacity;
- if (!newCapacity) newCapacity = 16; // TODO: figure out good value for minimum capacity
+ /// Create a representation from the slice. If slice is empty will return nullptr.
+ static StringRepresentation* create(const UnownedStringSlice& slice);
+ /// Same as create, but representation will have refcount of 1 (if not nullptr)
+ static StringRepresentation* createWithReference(const UnownedStringSlice& slice);
- while (newCapacity < required)
- {
- newCapacity = 2 * newCapacity;
- }
+ StringRepresentation* cloneWithCapacity(Index newCapacity)
+ {
+ StringRepresentation* newObj = createWithCapacityAndLength(newCapacity, length);
+ memcpy(getData(), newObj->getData(), length + 1);
+ return newObj;
+ }
- return cloneWithCapacity(newCapacity);
- }
+ StringRepresentation* clone() { return cloneWithCapacity(length); }
+
+ StringRepresentation* ensureCapacity(Index required)
+ {
+ if (capacity >= required)
+ return this;
- /// Overload delete to silence ASAN new-delete-type-mismatch errors.
- /// These occur because the allocation size of StringRepresentation
- /// does not match deallocation size (due variable sized string payload).
- void operator delete(void* p)
+ Index newCapacity = capacity;
+ if (!newCapacity)
+ newCapacity = 16; // TODO: figure out good value for minimum capacity
+
+ while (newCapacity < required)
{
- StringRepresentation* str = (StringRepresentation*) p;
- ::operator delete(str);
- }
- };
+ newCapacity = 2 * newCapacity;
+ }
- class String;
+ return cloneWithCapacity(newCapacity);
+ }
- struct SLANG_RT_API StringSlice
+ /// Overload delete to silence ASAN new-delete-type-mismatch errors.
+ /// These occur because the allocation size of StringRepresentation
+ /// does not match deallocation size (due variable sized string payload).
+ void operator delete(void* p)
{
- public:
- StringSlice();
+ StringRepresentation* str = (StringRepresentation*)p;
+ ::operator delete(str);
+ }
+};
- StringSlice(String const& str);
+class String;
- StringSlice(String const& str, UInt beginIndex, UInt endIndex);
+struct SLANG_RT_API StringSlice
+{
+public:
+ StringSlice();
- UInt getLength() const
- {
- return endIndex - beginIndex;
- }
+ StringSlice(String const& str);
- char const* begin() const
- {
- return representation ? representation->getData() + beginIndex : "";
- }
+ StringSlice(String const& str, UInt beginIndex, UInt endIndex);
- char const* end() const
- {
- return begin() + getLength();
- }
+ UInt getLength() const { return endIndex - beginIndex; }
- private:
- RefPtr<StringRepresentation> representation;
- UInt beginIndex;
- UInt endIndex;
+ char const* begin() const
+ {
+ return representation ? representation->getData() + beginIndex : "";
+ }
- friend class String;
+ char const* end() const { return begin() + getLength(); }
- StringSlice(RefPtr<StringRepresentation> const& representation, UInt beginIndex, UInt endIndex)
- : representation(representation)
- , beginIndex(beginIndex)
- , endIndex(endIndex)
- {}
- };
+private:
+ RefPtr<StringRepresentation> representation;
+ UInt beginIndex;
+ UInt endIndex;
- /// String as expected by underlying platform APIs
- class SLANG_RT_API OSString
- {
- public:
- /// Default
- OSString();
- /// NOTE! This assumes that begin is a new wchar_t[] buffer, and it will
- /// now be owned by the OSString
- OSString(wchar_t* begin, wchar_t* end);
- /// Move Ctor
- OSString(OSString&& rhs):
- m_begin(rhs.m_begin),
- m_end(rhs.m_end)
- {
- rhs.m_begin = nullptr;
- rhs.m_end = nullptr;
- }
- // Copy Ctor
- OSString(const OSString& rhs) :
- m_begin(nullptr),
- m_end(nullptr)
- {
- set(rhs.m_begin, rhs.m_end);
- }
+ friend class String;
- /// =
- void operator=(const OSString& rhs) { set(rhs.m_begin, rhs.m_end); }
- void operator=(OSString&& rhs)
- {
- auto begin = m_begin;
- auto end = m_end;
- m_begin = rhs.m_begin;
- m_end = rhs.m_end;
- rhs.m_begin = begin;
- rhs.m_end = end;
- }
+ StringSlice(RefPtr<StringRepresentation> const& representation, UInt beginIndex, UInt endIndex)
+ : representation(representation), beginIndex(beginIndex), endIndex(endIndex)
+ {
+ }
+};
- ~OSString() { _releaseBuffer(); }
+/// String as expected by underlying platform APIs
+class SLANG_RT_API OSString
+{
+public:
+ /// Default
+ OSString();
+ /// NOTE! This assumes that begin is a new wchar_t[] buffer, and it will
+ /// now be owned by the OSString
+ OSString(wchar_t* begin, wchar_t* end);
+ /// Move Ctor
+ OSString(OSString&& rhs)
+ : m_begin(rhs.m_begin), m_end(rhs.m_end)
+ {
+ rhs.m_begin = nullptr;
+ rhs.m_end = nullptr;
+ }
+ // Copy Ctor
+ OSString(const OSString& rhs)
+ : m_begin(nullptr), m_end(nullptr)
+ {
+ set(rhs.m_begin, rhs.m_end);
+ }
- size_t getLength() const { return (m_end - m_begin); }
- void set(const wchar_t* begin, const wchar_t* end);
+ /// =
+ void operator=(const OSString& rhs) { set(rhs.m_begin, rhs.m_end); }
+ void operator=(OSString&& rhs)
+ {
+ auto begin = m_begin;
+ auto end = m_end;
+ m_begin = rhs.m_begin;
+ m_end = rhs.m_end;
+ rhs.m_begin = begin;
+ rhs.m_end = end;
+ }
- operator wchar_t const*() const
- {
- return begin();
- }
+ ~OSString() { _releaseBuffer(); }
- wchar_t const* begin() const;
- wchar_t const* end() const;
+ size_t getLength() const { return (m_end - m_begin); }
+ void set(const wchar_t* begin, const wchar_t* end);
- private:
+ operator wchar_t const*() const { return begin(); }
- void _releaseBuffer();
+ wchar_t const* begin() const;
+ wchar_t const* end() const;
- wchar_t* m_begin; ///< First character. This is a new wchar_t[] buffer
- wchar_t* m_end; ///< Points to terminating 0
- };
+private:
+ void _releaseBuffer();
- /*!
- @brief Represents a UTF-8 encoded string.
- */
+ wchar_t* m_begin; ///< First character. This is a new wchar_t[] buffer
+ wchar_t* m_end; ///< Points to terminating 0
+};
- class SLANG_RT_API String
- {
- friend struct StringSlice;
- friend class StringBuilder;
- private:
+/*!
+@brief Represents a UTF-8 encoded string.
+*/
+class SLANG_RT_API String
+{
+ friend struct StringSlice;
+ friend class StringBuilder;
- char* getData() const
- {
- return m_buffer ? m_buffer->getData() : (char*)"";
- }
+private:
+ char* getData() const { return m_buffer ? m_buffer->getData() : (char*)""; }
-
- void ensureUniqueStorageWithCapacity(Index capacity);
-
- RefPtr<StringRepresentation> m_buffer;
- public:
+ void ensureUniqueStorageWithCapacity(Index capacity);
- explicit String(StringRepresentation* buffer)
- : m_buffer(buffer)
- {}
+ RefPtr<StringRepresentation> m_buffer;
- static String fromWString(const wchar_t* wstr);
- static String fromWString(const wchar_t* wstr, const wchar_t* wend);
- static String fromWChar(const wchar_t ch);
- static String fromUnicodePoint(Char32 codePoint);
+public:
+ explicit String(StringRepresentation* buffer)
+ : m_buffer(buffer)
+ {
+ }
- String()
- {
- }
+ static String fromWString(const wchar_t* wstr);
+ static String fromWString(const wchar_t* wstr, const wchar_t* wend);
+ static String fromWChar(const wchar_t ch);
+ static String fromUnicodePoint(Char32 codePoint);
- /// Returns a buffer which can hold at least count chars
- char* prepareForAppend(Index count);
- /// Append data written to buffer output via 'prepareForAppend' directly written 'inplace'
- void appendInPlace(const char* chars, Index count);
+ String() {}
- /// Get the internal string represenation
- SLANG_FORCE_INLINE StringRepresentation* getStringRepresentation() const { return m_buffer; }
+ /// Returns a buffer which can hold at least count chars
+ char* prepareForAppend(Index count);
+ /// Append data written to buffer output via 'prepareForAppend' directly written 'inplace'
+ void appendInPlace(const char* chars, Index count);
- /// Detach the representation (will leave string as empty). Rep ref count will remain unchanged.
- SLANG_FORCE_INLINE StringRepresentation* detachStringRepresentation() { return m_buffer.detach(); }
+ /// Get the internal string represenation
+ SLANG_FORCE_INLINE StringRepresentation* getStringRepresentation() const { return m_buffer; }
- const char* begin() const
- {
- return getData();
- }
- const char* end() const
- {
- return getData() + getLength();
- }
+ /// Detach the representation (will leave string as empty). Rep ref count will remain unchanged.
+ SLANG_FORCE_INLINE StringRepresentation* detachStringRepresentation()
+ {
+ return m_buffer.detach();
+ }
- void append(int32_t value, int radix = 10);
- void append(uint32_t value, int radix = 10);
- void append(int64_t value, int radix = 10);
- void append(uint64_t value, int radix = 10);
- void append(float val, const char* format = "%g");
- void append(double val, const char* format = "%g");
+ const char* begin() const { return getData(); }
+ const char* end() const { return getData() + getLength(); }
- // Padded hex representations
- void append(StableHashCode32 val);
- void append(StableHashCode64 val);
+ void append(int32_t value, int radix = 10);
+ void append(uint32_t value, int radix = 10);
+ void append(int64_t value, int radix = 10);
+ void append(uint64_t value, int radix = 10);
+ void append(float val, const char* format = "%g");
+ void append(double val, const char* format = "%g");
- void append(char const* str);
- void append(char const* str, size_t len);
- void append(const char* textBegin, char const* textEnd);
- void append(char chr);
- void append(String const& str);
- void append(StringSlice const& slice);
- void append(UnownedStringSlice const& slice);
+ // Padded hex representations
+ void append(StableHashCode32 val);
+ void append(StableHashCode64 val);
- /// Append a character (to remove ambiguity with other integral types)
- void appendChar(char chr);
+ void append(char const* str);
+ void append(char const* str, size_t len);
+ void append(const char* textBegin, char const* textEnd);
+ void append(char chr);
+ void append(String const& str);
+ void append(StringSlice const& slice);
+ void append(UnownedStringSlice const& slice);
- /// Append the specified char count times
- void appendRepeatedChar(char chr, Index count);
+ /// Append a character (to remove ambiguity with other integral types)
+ void appendChar(char chr);
- String(const char* str)
- {
- append(str);
+ /// Append the specified char count times
+ void appendRepeatedChar(char chr, Index count);
- }
- String(const char* textBegin, char const* textEnd)
- {
- append(textBegin, textEnd);
- }
+ String(const char* str) { append(str); }
+ String(const char* textBegin, char const* textEnd) { append(textBegin, textEnd); }
- // Make all String ctors from a numeric explicit, to avoid unexpected/unnecessary conversions
- explicit String(int32_t val, int radix = 10)
- {
- append(val, radix);
- }
- explicit String(uint32_t val, int radix = 10)
- {
- append(val, radix);
- }
- explicit String(int64_t val, int radix = 10)
- {
- append(val, radix);
- }
- explicit String(uint64_t val, int radix = 10)
- {
- append(val, radix);
- }
- explicit String(StableHashCode32 val)
- {
- append(val);
- }
- explicit String(StableHashCode64 val)
- {
- append(val);
- }
- explicit String(float val, const char* format = "%g")
- {
- append(val, format);
- }
- explicit String(double val, const char* format = "%g")
- {
- append(val, format);
- }
+ // Make all String ctors from a numeric explicit, to avoid unexpected/unnecessary conversions
+ explicit String(int32_t val, int radix = 10) { append(val, radix); }
+ explicit String(uint32_t val, int radix = 10) { append(val, radix); }
+ explicit String(int64_t val, int radix = 10) { append(val, radix); }
+ explicit String(uint64_t val, int radix = 10) { append(val, radix); }
+ explicit String(StableHashCode32 val) { append(val); }
+ explicit String(StableHashCode64 val) { append(val); }
+ explicit String(float val, const char* format = "%g") { append(val, format); }
+ explicit String(double val, const char* format = "%g") { append(val, format); }
- explicit String(char chr)
- {
- appendChar(chr);
- }
- String(String const& str)
- {
- m_buffer = str.m_buffer;
- }
- String(String&& other)
- {
- m_buffer = _Move(other.m_buffer);
- }
+ explicit String(char chr) { appendChar(chr); }
+ String(String const& str) { m_buffer = str.m_buffer; }
+ String(String&& other) { m_buffer = _Move(other.m_buffer); }
- String(StringSlice const& slice)
- {
- append(slice);
- }
+ String(StringSlice const& slice) { append(slice); }
- String(UnownedStringSlice const& slice)
- {
- append(slice);
- }
+ String(UnownedStringSlice const& slice) { append(slice); }
- ~String()
- {
- m_buffer.setNull();
- }
+ ~String() { m_buffer.setNull(); }
- String& operator=(const String& str)
- {
- m_buffer = str.m_buffer;
- return *this;
- }
- String& operator=(String&& other)
- {
- m_buffer = _Move(other.m_buffer);
- return *this;
- }
- char operator[](Index id) const
- {
- SLANG_ASSERT(id >= 0 && id < getLength());
- // Silence a pedantic warning on GCC
+ String& operator=(const String& str)
+ {
+ m_buffer = str.m_buffer;
+ return *this;
+ }
+ String& operator=(String&& other)
+ {
+ m_buffer = _Move(other.m_buffer);
+ return *this;
+ }
+ char operator[](Index id) const
+ {
+ SLANG_ASSERT(id >= 0 && id < getLength());
+ // Silence a pedantic warning on GCC
#if __GNUC__
- if(id < 0) __builtin_unreachable();
+ if (id < 0)
+ __builtin_unreachable();
#endif
- return begin()[id];
- }
+ return begin()[id];
+ }
- Index getLength() const
- {
- return m_buffer ? m_buffer->getLength() : 0;
- }
- /// Make the length of the string the amount specified. Must be less than current size
- void reduceLength(Index length);
-
- friend String operator+(const char*op1, const String & op2);
- friend String operator+(const String & op1, const char * op2);
- friend String operator+(const String & op1, const String & op2);
-
- StringSlice trimStart() const
- {
- if (!m_buffer)
- return StringSlice();
- Index startIndex = 0;
- const char*const data = getData();
- while (startIndex < getLength() &&
- (data[startIndex] == ' ' || data[startIndex] == '\t' || data[startIndex] == '\r' || data[startIndex] == '\n'))
- startIndex++;
- return StringSlice(m_buffer, startIndex, getLength());
- }
+ Index getLength() const { return m_buffer ? m_buffer->getLength() : 0; }
+ /// Make the length of the string the amount specified. Must be less than current size
+ void reduceLength(Index length);
- StringSlice trimEnd() const
- {
- if (!m_buffer)
- return StringSlice();
+ friend String operator+(const char* op1, const String& op2);
+ friend String operator+(const String& op1, const char* op2);
+ friend String operator+(const String& op1, const String& op2);
- Index endIndex = getLength();
- const char*const data = getData();
- while (endIndex > 0 &&
- (data[endIndex-1] == ' ' || data[endIndex-1] == '\t' || data[endIndex-1] == '\r' || data[endIndex-1] == '\n'))
- endIndex--;
+ StringSlice trimStart() const
+ {
+ if (!m_buffer)
+ return StringSlice();
+ Index startIndex = 0;
+ const char* const data = getData();
+ while (startIndex < getLength() && (data[startIndex] == ' ' || data[startIndex] == '\t' ||
+ data[startIndex] == '\r' || data[startIndex] == '\n'))
+ startIndex++;
+ return StringSlice(m_buffer, startIndex, getLength());
+ }
- return StringSlice(m_buffer, 0, endIndex);
- }
+ StringSlice trimEnd() const
+ {
+ if (!m_buffer)
+ return StringSlice();
- StringSlice trim() const
- {
- if (!m_buffer)
- return StringSlice();
-
- Index startIndex = 0;
- const char*const data = getData();
- while (startIndex < getLength() &&
- (data[startIndex] == ' ' || data[startIndex] == '\t' || data[startIndex] == '\r' || data[startIndex] == '\n'))
- startIndex++;
- Index endIndex = getLength();
- while (endIndex > startIndex &&
- (data[endIndex-1] == ' ' || data[endIndex-1] == '\t' || data[endIndex-1] == '\r' || data[endIndex-1] == '\n'))
- endIndex--;
-
- return StringSlice(m_buffer, startIndex, endIndex);
- }
+ Index endIndex = getLength();
+ const char* const data = getData();
+ while (endIndex > 0 && (data[endIndex - 1] == ' ' || data[endIndex - 1] == '\t' ||
+ data[endIndex - 1] == '\r' || data[endIndex - 1] == '\n'))
+ endIndex--;
- StringSlice subString(Index id, Index len) const
- {
- if (len == 0)
- return StringSlice();
+ return StringSlice(m_buffer, 0, endIndex);
+ }
+
+ StringSlice trim() const
+ {
+ if (!m_buffer)
+ return StringSlice();
+
+ Index startIndex = 0;
+ const char* const data = getData();
+ while (startIndex < getLength() && (data[startIndex] == ' ' || data[startIndex] == '\t' ||
+ data[startIndex] == '\r' || data[startIndex] == '\n'))
+ startIndex++;
+ Index endIndex = getLength();
+ while (endIndex > startIndex && (data[endIndex - 1] == ' ' || data[endIndex - 1] == '\t' ||
+ data[endIndex - 1] == '\r' || data[endIndex - 1] == '\n'))
+ endIndex--;
+
+ return StringSlice(m_buffer, startIndex, endIndex);
+ }
+
+ StringSlice subString(Index id, Index len) const
+ {
+ if (len == 0)
+ return StringSlice();
- if (id + len > getLength())
- len = getLength() - id;
+ if (id + len > getLength())
+ len = getLength() - id;
#if _DEBUG
- if (id < 0 || id >= getLength() || (id + len) > getLength())
- SLANG_ASSERT_FAILURE("SubString: index out of range.");
- if (len < 0)
- SLANG_ASSERT_FAILURE("SubString: length less than zero.");
+ if (id < 0 || id >= getLength() || (id + len) > getLength())
+ SLANG_ASSERT_FAILURE("SubString: index out of range.");
+ if (len < 0)
+ SLANG_ASSERT_FAILURE("SubString: length less than zero.");
#endif
- return StringSlice(m_buffer, id, id + len);
- }
+ return StringSlice(m_buffer, id, id + len);
+ }
- char const* getBuffer() const
- {
- return getData();
- }
+ char const* getBuffer() const { return getData(); }
- OSString toWString(Index* len = 0) const;
+ OSString toWString(Index* len = 0) const;
- bool equals(const String& str, bool caseSensitive = true)
+ bool equals(const String& str, bool caseSensitive = true)
+ {
+ if (caseSensitive)
+ return (strcmp(begin(), str.begin()) == 0);
+ else
{
- if (caseSensitive)
- return (strcmp(begin(), str.begin()) == 0);
- else
- {
#ifdef _MSC_VER
- return (_stricmp(begin(), str.begin()) == 0);
+ return (_stricmp(begin(), str.begin()) == 0);
#else
- return (strcasecmp(begin(), str.begin()) == 0);
+ return (strcasecmp(begin(), str.begin()) == 0);
#endif
- }
- }
- bool operator==(const char* strbuffer) const
- {
- return (strcmp(begin(), strbuffer) == 0);
- }
-
- bool operator==(const String& str) const
- {
- return (strcmp(begin(), str.begin()) == 0);
- }
- bool operator!=(const char* strbuffer) const
- {
- return (strcmp(begin(), strbuffer) != 0);
- }
- bool operator!=(const String& str) const
- {
- return (strcmp(begin(), str.begin()) != 0);
- }
- bool operator>(const String& str) const
- {
- return (strcmp(begin(), str.begin()) > 0);
- }
- bool operator<(const String& str) const
- {
- return (strcmp(begin(), str.begin()) < 0);
- }
- bool operator>=(const String& str) const
- {
- return (strcmp(begin(), str.begin()) >= 0);
- }
- bool operator<=(const String& str) const
- {
- return (strcmp(begin(), str.begin()) <= 0);
}
+ }
+ bool operator==(const char* strbuffer) const { return (strcmp(begin(), strbuffer) == 0); }
- SLANG_FORCE_INLINE bool operator==(const UnownedStringSlice& slice) const { return getUnownedSlice() == slice; }
- SLANG_FORCE_INLINE bool operator!=(const UnownedStringSlice& slice) const { return getUnownedSlice() != slice; }
+ bool operator==(const String& str) const { return (strcmp(begin(), str.begin()) == 0); }
+ bool operator!=(const char* strbuffer) const { return (strcmp(begin(), strbuffer) != 0); }
+ bool operator!=(const String& str) const { return (strcmp(begin(), str.begin()) != 0); }
+ bool operator>(const String& str) const { return (strcmp(begin(), str.begin()) > 0); }
+ bool operator<(const String& str) const { return (strcmp(begin(), str.begin()) < 0); }
+ bool operator>=(const String& str) const { return (strcmp(begin(), str.begin()) >= 0); }
+ bool operator<=(const String& str) const { return (strcmp(begin(), str.begin()) <= 0); }
- String toUpper() const
- {
- String result;
- for (auto c : *this)
- {
- char d = (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;
- result.append(d);
- }
- return result;
- }
+ SLANG_FORCE_INLINE bool operator==(const UnownedStringSlice& slice) const
+ {
+ return getUnownedSlice() == slice;
+ }
+ SLANG_FORCE_INLINE bool operator!=(const UnownedStringSlice& slice) const
+ {
+ return getUnownedSlice() != slice;
+ }
- String toLower() const
+ String toUpper() const
+ {
+ String result;
+ for (auto c : *this)
{
- String result;
- for (auto c : *this)
- {
- char d = (c >= 'A' && c <= 'Z') ? (c - ('A' - 'a')) : c;
- result.append(d);
- }
- return result;
+ char d = (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;
+ result.append(d);
}
+ return result;
+ }
- Index indexOf(const char* str, Index id) const // String str
+ String toLower() const
+ {
+ String result;
+ for (auto c : *this)
{
- if (id >= getLength())
- return Index(-1);
- auto findRs = strstr(begin() + id, str);
- Index res = findRs ? findRs - begin() : Index(-1);
- return res;
+ char d = (c >= 'A' && c <= 'Z') ? (c - ('A' - 'a')) : c;
+ result.append(d);
}
+ return result;
+ }
- Index indexOf(const String& str, Index id) const
- {
- return indexOf(str.begin(), id);
- }
+ Index indexOf(const char* str, Index id) const // String str
+ {
+ if (id >= getLength())
+ return Index(-1);
+ auto findRs = strstr(begin() + id, str);
+ Index res = findRs ? findRs - begin() : Index(-1);
+ return res;
+ }
- Index indexOf(const char* str) const
- {
- return indexOf(str, 0);
- }
+ Index indexOf(const String& str, Index id) const { return indexOf(str.begin(), id); }
- Index indexOf(const String& str) const
- {
- return indexOf(str.begin(), 0);
- }
+ Index indexOf(const char* str) const { return indexOf(str, 0); }
- void swapWith(String& other)
- {
- m_buffer.swapWith(other.m_buffer);
- }
+ Index indexOf(const String& str) const { return indexOf(str.begin(), 0); }
- Index indexOf(char ch, Index id) const
- {
- const Index length = getLength();
- SLANG_ASSERT(id >= 0 && id <= length);
+ void swapWith(String& other) { m_buffer.swapWith(other.m_buffer); }
- if (!m_buffer)
- return Index(-1);
+ Index indexOf(char ch, Index id) const
+ {
+ const Index length = getLength();
+ SLANG_ASSERT(id >= 0 && id <= length);
- const char* data = getData();
- for (Index i = id; i < length; i++)
- if (data[i] == ch)
- return i;
+ if (!m_buffer)
return Index(-1);
- }
-
- Index indexOf(char ch) const
- {
- return indexOf(ch, 0);
- }
- Index lastIndexOf(char ch) const
- {
- const Index length = getLength();
- const char* data = getData();
+ const char* data = getData();
+ for (Index i = id; i < length; i++)
+ if (data[i] == ch)
+ return i;
+ return Index(-1);
+ }
- for (Index i = length - 1; i >= 0; --i)
- if (data[i] == ch)
- return i;
- return Index(-1);
- }
+ Index indexOf(char ch) const { return indexOf(ch, 0); }
- bool startsWith(const char* str) const
- {
- if (!m_buffer)
- return false;
- Index strLen = Index(::strlen(str));
- if (strLen > getLength())
- return false;
+ Index lastIndexOf(char ch) const
+ {
+ const Index length = getLength();
+ const char* data = getData();
- const char*const data = getData();
+ for (Index i = length - 1; i >= 0; --i)
+ if (data[i] == ch)
+ return i;
+ return Index(-1);
+ }
- for (Index i = 0; i < strLen; i++)
- if (str[i] != data[i])
- return false;
- return true;
- }
+ bool startsWith(const char* str) const
+ {
+ if (!m_buffer)
+ return false;
+ Index strLen = Index(::strlen(str));
+ if (strLen > getLength())
+ return false;
- bool startsWith(const String& str) const
- {
- return startsWith(str.begin());
- }
+ const char* const data = getData();
- bool endsWith(char const* str) const // String str
- {
- if (!m_buffer)
+ for (Index i = 0; i < strLen; i++)
+ if (str[i] != data[i])
return false;
+ return true;
+ }
+
+ bool startsWith(const String& str) const { return startsWith(str.begin()); }
+
+ bool endsWith(char const* str) const // String str
+ {
+ if (!m_buffer)
+ return false;
- const Index strLen = Index(::strlen(str));
- const Index len = getLength();
+ const Index strLen = Index(::strlen(str));
+ const Index len = getLength();
- if (strLen > len)
+ if (strLen > len)
+ return false;
+ const char* data = getData();
+ for (Index i = strLen; i > 0; i--)
+ if (str[i - 1] != data[len - strLen + i - 1])
return false;
- const char* data = getData();
- for (Index i = strLen; i > 0; i--)
- if (str[i-1] != data[len - strLen + i-1])
- return false;
- return true;
- }
+ return true;
+ }
- bool endsWith(const String& str) const
- {
- return endsWith(str.begin());
- }
+ bool endsWith(const String& str) const { return endsWith(str.begin()); }
- bool contains(const char* str) const // String str
- {
- return m_buffer && indexOf(str) != Index(-1);
- }
+ bool contains(const char* str) const // String str
+ {
+ return m_buffer && indexOf(str) != Index(-1);
+ }
- bool contains(const String& str) const
- {
- return contains(str.begin());
- }
+ bool contains(const String& str) const { return contains(str.begin()); }
- static constexpr bool kHasUniformHash = true;
- HashCode64 getHashCode() const
- {
- return Slang::getHashCode(StringRepresentation::asSlice(m_buffer));
- }
+ static constexpr bool kHasUniformHash = true;
+ HashCode64 getHashCode() const
+ {
+ return Slang::getHashCode(StringRepresentation::asSlice(m_buffer));
+ }
- UnownedStringSlice getUnownedSlice() const
- {
- return StringRepresentation::asSlice(m_buffer);
- }
- };
+ UnownedStringSlice getUnownedSlice() const { return StringRepresentation::asSlice(m_buffer); }
+};
- class SLANG_RT_API StringBuilder : public String
+class SLANG_RT_API StringBuilder : public String
+{
+private:
+ enum
{
- private:
- enum { InitialSize = 1024 };
- public:
- typedef String Super;
- using Super::append;
+ InitialSize = 1024
+ };
- explicit StringBuilder(UInt bufferSize = InitialSize)
- {
- ensureUniqueStorageWithCapacity(bufferSize);
- }
+public:
+ typedef String Super;
+ using Super::append;
- void ensureCapacity(UInt size)
- {
- ensureUniqueStorageWithCapacity(size);
- }
- StringBuilder& operator << (char ch)
- {
- appendChar(ch);
- return *this;
- }
- StringBuilder& operator << (Int32 val)
- {
- append(val);
- return *this;
- }
- StringBuilder& operator << (UInt32 val)
- {
- append(val);
- return *this;
- }
- StringBuilder& operator << (Int64 val)
- {
- append(val);
- return *this;
- }
- StringBuilder& operator << (UInt64 val)
- {
- append(val);
- return *this;
- }
- StringBuilder& operator << (float val)
- {
- append(val);
- return *this;
- }
- StringBuilder& operator << (double val)
- {
- append(val);
- return *this;
- }
- StringBuilder& operator << (const char* str)
- {
- append(str, strlen(str));
- return *this;
- }
- StringBuilder& operator << (const String& str)
- {
- append(str);
- return *this;
- }
- StringBuilder& operator << (UnownedStringSlice const& str)
- {
- append(str);
- return *this;
- }
- StringBuilder& operator << (const _EndLine)
- {
- appendChar('\n');
- return *this;
- }
+ explicit StringBuilder(UInt bufferSize = InitialSize)
+ {
+ ensureUniqueStorageWithCapacity(bufferSize);
+ }
- String toString()
- {
- return *this;
- }
+ void ensureCapacity(UInt size) { ensureUniqueStorageWithCapacity(size); }
+ StringBuilder& operator<<(char ch)
+ {
+ appendChar(ch);
+ return *this;
+ }
+ StringBuilder& operator<<(Int32 val)
+ {
+ append(val);
+ return *this;
+ }
+ StringBuilder& operator<<(UInt32 val)
+ {
+ append(val);
+ return *this;
+ }
+ StringBuilder& operator<<(Int64 val)
+ {
+ append(val);
+ return *this;
+ }
+ StringBuilder& operator<<(UInt64 val)
+ {
+ append(val);
+ return *this;
+ }
+ StringBuilder& operator<<(float val)
+ {
+ append(val);
+ return *this;
+ }
+ StringBuilder& operator<<(double val)
+ {
+ append(val);
+ return *this;
+ }
+ StringBuilder& operator<<(const char* str)
+ {
+ append(str, strlen(str));
+ return *this;
+ }
+ StringBuilder& operator<<(const String& str)
+ {
+ append(str);
+ return *this;
+ }
+ StringBuilder& operator<<(UnownedStringSlice const& str)
+ {
+ append(str);
+ return *this;
+ }
+ StringBuilder& operator<<(const _EndLine)
+ {
+ appendChar('\n');
+ return *this;
+ }
- String produceString()
- {
- return *this;
- }
+ String toString() { return *this; }
+
+ String produceString() { return *this; }
#if 0
void Remove(int id, int len)
@@ -1000,20 +883,17 @@ namespace Slang
length -= actualDelLength;
}
#endif
- friend std::ostream& operator<< (std::ostream& stream, const String& s);
+ friend std::ostream& operator<<(std::ostream& stream, const String& s);
- void clear()
- {
- m_buffer.setNull();
- }
- };
+ void clear() { m_buffer.setNull(); }
+};
- int stringToInt(const String& str, int radix = 10);
- unsigned int stringToUInt(const String& str, int radix = 10);
- double stringToDouble(const String& str);
- float stringToFloat(const String& str);
-}
+int stringToInt(const String& str, int radix = 10);
+unsigned int stringToUInt(const String& str, int radix = 10);
+double stringToDouble(const String& str);
+float stringToFloat(const String& str);
+} // namespace Slang
-std::ostream& operator<< (std::ostream& stream, const Slang::String& s);
+std::ostream& operator<<(std::ostream& stream, const Slang::String& s);
#endif
diff --git a/source/core/slang-test-tool-util.cpp b/source/core/slang-test-tool-util.cpp
index d362d7043..a71048f10 100644
--- a/source/core/slang-test-tool-util.cpp
+++ b/source/core/slang-test-tool-util.cpp
@@ -2,29 +2,28 @@
#include "slang-test-tool-util.h"
#include "slang-com-helper.h"
-
#include "slang-io.h"
#include "slang-string-util.h"
namespace Slang
{
-/* static */ToolReturnCode TestToolUtil::getReturnCode(SlangResult res)
+/* static */ ToolReturnCode TestToolUtil::getReturnCode(SlangResult res)
{
switch (res)
{
- case SLANG_OK: return ToolReturnCode::Success;
- case SLANG_E_INTERNAL_FAIL: return ToolReturnCode::CompilationFailed;
- case SLANG_FAIL: return ToolReturnCode::Failed;
- case SLANG_E_NOT_AVAILABLE: return ToolReturnCode::Ignored;
- default:
+ case SLANG_OK: return ToolReturnCode::Success;
+ case SLANG_E_INTERNAL_FAIL: return ToolReturnCode::CompilationFailed;
+ case SLANG_FAIL: return ToolReturnCode::Failed;
+ case SLANG_E_NOT_AVAILABLE: return ToolReturnCode::Ignored;
+ default:
{
return (SLANG_SUCCEEDED(res)) ? ToolReturnCode::Success : ToolReturnCode::Failed;
}
}
}
-/* static */ToolReturnCode TestToolUtil::getReturnCodeFromInt(int code)
+/* static */ ToolReturnCode TestToolUtil::getReturnCodeFromInt(int code)
{
if (code >= int(ToolReturnCodeSpan::First) && code <= int(ToolReturnCodeSpan::Last))
{
@@ -37,7 +36,7 @@ namespace Slang
}
}
-/* static */bool TestToolUtil::hasDeferredCoreModule(Index argc, const char*const* argv)
+/* static */ bool TestToolUtil::hasDeferredCoreModule(Index argc, const char* const* argv)
{
for (Index i = 0; i < argc; ++i)
{
@@ -50,7 +49,10 @@ namespace Slang
return false;
}
-/* static */SlangResult TestToolUtil::getIncludePath(const String& parentPath, const char* path, String& outIncludePath)
+/* static */ SlangResult TestToolUtil::getIncludePath(
+ const String& parentPath,
+ const char* path,
+ String& outIncludePath)
{
String includePath;
SLANG_RETURN_ON_FAIL(Path::getCanonical(Path::combine(parentPath, path), includePath));
@@ -73,7 +75,10 @@ static SlangResult _addCPPPrelude(const String& rootPath, slang::IGlobalSession*
String includePath;
SlangResult res = SLANG_FAIL;
if (SLANG_FAILED(res))
- res = TestToolUtil::getIncludePath(Path::combine(rootPath, "include"), "slang-cpp-prelude.h", includePath);
+ res = TestToolUtil::getIncludePath(
+ Path::combine(rootPath, "include"),
+ "slang-cpp-prelude.h",
+ includePath);
if (SLANG_FAILED(res))
res = TestToolUtil::getIncludePath(rootPath, "prelude/slang-cpp-prelude.h", includePath);
SLANG_RETURN_ON_FAIL(res);
@@ -88,7 +93,10 @@ static SlangResult _addCUDAPrelude(const String& rootPath, slang::IGlobalSession
String includePath;
SlangResult res = SLANG_FAIL;
if (SLANG_FAILED(res))
- res = TestToolUtil::getIncludePath(Path::combine(rootPath, "include"), "slang-cuda-prelude.h", includePath);
+ res = TestToolUtil::getIncludePath(
+ Path::combine(rootPath, "include"),
+ "slang-cuda-prelude.h",
+ includePath);
if (SLANG_FAILED(res))
res = TestToolUtil::getIncludePath(rootPath, "prelude/slang-cuda-prelude.h", includePath);
SLANG_RETURN_ON_FAIL(res);
@@ -98,7 +106,9 @@ static SlangResult _addCUDAPrelude(const String& rootPath, slang::IGlobalSession
return SLANG_OK;
}
-/* static */SlangResult TestToolUtil::getExeDirectoryPath(const char* exePath, String& outExeDirectoryPath)
+/* static */ SlangResult TestToolUtil::getExeDirectoryPath(
+ const char* exePath,
+ String& outExeDirectoryPath)
{
String canonicalPath;
SLANG_RETURN_ON_FAIL(Path::getCanonical(exePath, canonicalPath));
@@ -107,7 +117,9 @@ static SlangResult _addCUDAPrelude(const String& rootPath, slang::IGlobalSession
return SLANG_OK;
}
-/* static */SlangResult TestToolUtil::getDllDirectoryPath(const char* exePath, String& outDllDirectoryPath)
+/* static */ SlangResult TestToolUtil::getDllDirectoryPath(
+ const char* exePath,
+ String& outDllDirectoryPath)
{
String canonicalPath;
SLANG_RETURN_ON_FAIL(Path::getCanonical(exePath, canonicalPath));
@@ -115,7 +127,8 @@ static SlangResult _addCUDAPrelude(const String& rootPath, slang::IGlobalSession
// Get the directory
String binPath = Path::getParentDirectory(canonicalPath);
- // Windows puts the dlls in the same directory as the exe, while on other platforms they are in a 'lib' directory
+ // Windows puts the dlls in the same directory as the exe, while on other platforms they are in
+ // a 'lib' directory
#ifdef _WIN32
outDllDirectoryPath = binPath;
#else
@@ -125,7 +138,7 @@ static SlangResult _addCUDAPrelude(const String& rootPath, slang::IGlobalSession
return SLANG_OK;
}
-/* static */SlangResult TestToolUtil::getRootPath(const char* inExePath, String& outExePath)
+/* static */ SlangResult TestToolUtil::getRootPath(const char* inExePath, String& outExePath)
{
// Get the directory holding the exe
String parentPath;
@@ -137,21 +150,23 @@ static SlangResult _addCUDAPrelude(const String& rootPath, slang::IGlobalSession
SLANG_RETURN_ON_FAIL(Path::getCanonical(parentPath, rootRelPath));
do
{
- if(File::exists(Path::combine(rootRelPath, "include/slang-cpp-prelude.h")))
+ if (File::exists(Path::combine(rootRelPath, "include/slang-cpp-prelude.h")))
break;
- if(File::exists(Path::combine(rootRelPath, "prelude/slang-cpp-prelude.h")))
+ if (File::exists(Path::combine(rootRelPath, "prelude/slang-cpp-prelude.h")))
break;
rootRelPath = Path::getParentDirectory(rootRelPath);
- if(rootRelPath == "")
+ if (rootRelPath == "")
return SLANG_E_NOT_AVAILABLE;
- } while(1);
+ } while (1);
outExePath = std::move(rootRelPath);
return SLANG_OK;
}
-/* static */SlangResult TestToolUtil::setSessionDefaultPreludeFromExePath(const char* inExePath, slang::IGlobalSession* session)
+/* static */ SlangResult TestToolUtil::setSessionDefaultPreludeFromExePath(
+ const char* inExePath,
+ slang::IGlobalSession* session)
{
String rootPath;
SLANG_RETURN_ON_FAIL(getRootPath(inExePath, rootPath));
@@ -159,10 +174,12 @@ static SlangResult _addCUDAPrelude(const String& rootPath, slang::IGlobalSession
return SLANG_OK;
}
-/* static */SlangResult TestToolUtil::setSessionDefaultPreludeFromRootPath(const String& rootPath, slang::IGlobalSession* session)
+/* static */ SlangResult TestToolUtil::setSessionDefaultPreludeFromRootPath(
+ const String& rootPath,
+ slang::IGlobalSession* session)
{
// Set the prelude to a path
-
+
if (SLANG_FAILED(_addCPPPrelude(rootPath, session)))
{
SLANG_ASSERT(!"Couldn't find the C++ prelude relative to the executable");
@@ -172,9 +189,8 @@ static SlangResult _addCUDAPrelude(const String& rootPath, slang::IGlobalSession
{
SLANG_ASSERT(!"Couldn't find the CUDA prelude relative to the executable");
}
-
- return SLANG_OK;
-}
+ return SLANG_OK;
}
+} // namespace Slang
diff --git a/source/core/slang-test-tool-util.h b/source/core/slang-test-tool-util.h
index 967dc0fa8..241166111 100644
--- a/source/core/slang-test-tool-util.h
+++ b/source/core/slang-test-tool-util.h
@@ -3,24 +3,27 @@
#include "slang-std-writers.h"
-namespace Slang {
+namespace Slang
+{
#ifdef SLANG_SHARED_LIBRARY_TOOL
-# define SLANG_TEST_TOOL_API SLANG_EXTERN_C SLANG_DLL_EXPORT
+#define SLANG_TEST_TOOL_API SLANG_EXTERN_C SLANG_DLL_EXPORT
#else
-# define SLANG_TEST_TOOL_API
+#define SLANG_TEST_TOOL_API
#endif
/* When a tool is run as an executable the return code is the code returned from
-the last return of main. On unix this can be up to 8 bits.
+the last return of main. On unix this can be up to 8 bits.
By normal command line tool conventions returning 0 means success. */
enum class ToolReturnCode
{
- CompilationFailed = -1, ///< Compilation failure (-1 to maintain compatibility). This may still produce output and may mean a test was successful.
- Success = 0, ///< Tool ran normally
- Failed, ///< Tool failed
- Ignored, ///< The run was ignored because it couldn't be run (because some optional feature was not present for example)
- FailedToRun, ///< Could not even run the test
+ CompilationFailed = -1, ///< Compilation failure (-1 to maintain compatibility). This may still
+ ///< produce output and may mean a test was successful.
+ Success = 0, ///< Tool ran normally
+ Failed, ///< Tool failed
+ Ignored, ///< The run was ignored because it couldn't be run (because some optional feature was
+ ///< not present for example)
+ FailedToRun, ///< Could not even run the test
};
enum class ToolReturnCodeSpan
@@ -36,36 +39,53 @@ enum class ToolReturnCodeSpan
/* Utility functions for 'test tools' */
struct TestToolUtil
{
- typedef SlangResult(*InnerMainFunc)(Slang::StdWriters* stdWriters, SlangSession* session, int argc, const char*const* argv);
-
- /// If the test failed to run or was ignored then we are done
- static bool isDone(ToolReturnCode code) { return int(code) >= int(ToolReturnCodeSpan::FirstIsDone) && int(code) <= int(ToolReturnCodeSpan::LastIsDone); }
-
- /// Convert from an int
+ typedef SlangResult (*InnerMainFunc)(
+ Slang::StdWriters* stdWriters,
+ SlangSession* session,
+ int argc,
+ const char* const* argv);
+
+ /// If the test failed to run or was ignored then we are done
+ static bool isDone(ToolReturnCode code)
+ {
+ return int(code) >= int(ToolReturnCodeSpan::FirstIsDone) &&
+ int(code) <= int(ToolReturnCodeSpan::LastIsDone);
+ }
+
+ /// Convert from an int
static ToolReturnCode getReturnCodeFromInt(int code);
- /// Given a slang result, returns a return code that can be returned from an executable
+ /// Given a slang result, returns a return code that can be returned from an executable
static ToolReturnCode getReturnCode(SlangResult res);
- /// Given the executable path (as located in Slang directory hierarchy), works out the absolute path to the root
+ /// Given the executable path (as located in Slang directory hierarchy), works out the absolute
+ /// path to the root
static SlangResult getRootPath(const char* exePath, String& outRootPath);
- /// Given the exePath, give return the absolute path to the directory the exe is in
+ /// Given the exePath, give return the absolute path to the directory the exe is in
static SlangResult getExeDirectoryPath(const char* exePath, String& outExeDirectoryPath);
- /// Sets the default preludes on the session based on an explicit path
- static SlangResult setSessionDefaultPreludeFromRootPath(const String& rootPath, slang::IGlobalSession* session);
+ /// Sets the default preludes on the session based on an explicit path
+ static SlangResult setSessionDefaultPreludeFromRootPath(
+ const String& rootPath,
+ slang::IGlobalSession* session);
+
+ /// Calculates the path that is the combination of parentPath, and relPath
+ /// And converts such that can be used as an include path (handling slashes)
+ static SlangResult getIncludePath(
+ const String& parentPath,
+ const char* relPath,
+ String& outIncludePath);
- /// Calculates the path that is the combination of parentPath, and relPath
- /// And converts such that can be used as an include path (handling slashes)
- static SlangResult getIncludePath(const String& parentPath, const char* relPath, String& outIncludePath);
-
- /// Sets the default preludes on the session based on the executable path
- static SlangResult setSessionDefaultPreludeFromExePath(const char* exePath, slang::IGlobalSession* session);
+ /// Sets the default preludes on the session based on the executable path
+ static SlangResult setSessionDefaultPreludeFromExePath(
+ const char* exePath,
+ slang::IGlobalSession* session);
- /// Returns true if the core module should not be initialized immediately (eg when doing a -load-core-module).
- static bool hasDeferredCoreModule(Index numArgs, const char*const* args);
+ /// Returns true if the core module should not be initialized immediately (eg when doing a
+ /// -load-core-module).
+ static bool hasDeferredCoreModule(Index numArgs, const char* const* args);
static SlangResult getDllDirectoryPath(const char* exePath, String& outDllDirectoryPath);
};
diff --git a/source/core/slang-text-io.cpp b/source/core/slang-text-io.cpp
index f7257c1ee..9cc3896fd 100644
--- a/source/core/slang-text-io.cpp
+++ b/source/core/slang-text-io.cpp
@@ -16,16 +16,16 @@ SlangResult StreamWriter::init(const String& path, CharEncoding* encoding)
SlangResult StreamWriter::init(RefPtr<Stream> stream, CharEncoding* encoding)
{
- m_stream = stream;
- m_encoding = encoding;
- if (encoding == CharEncoding::UTF16)
- {
- SLANG_RETURN_ON_FAIL(m_stream->write(&kUTF16Header, 2));
- }
- else if (encoding == CharEncoding::UTF16Reversed)
- {
- SLANG_RETURN_ON_FAIL(m_stream->write(&kUTF16ReversedHeader, 2));
- }
+ m_stream = stream;
+ m_encoding = encoding;
+ if (encoding == CharEncoding::UTF16)
+ {
+ SLANG_RETURN_ON_FAIL(m_stream->write(&kUTF16Header, 2));
+ }
+ else if (encoding == CharEncoding::UTF16Reversed)
+ {
+ SLANG_RETURN_ON_FAIL(m_stream->write(&kUTF16ReversedHeader, 2));
+ }
return SLANG_OK;
}
@@ -33,42 +33,42 @@ SlangResult StreamWriter::init(RefPtr<Stream> stream, CharEncoding* encoding)
SlangResult StreamWriter::writeSlice(const UnownedStringSlice& slice)
{
// TODO(JS):
- // We can do better here. On Linux, this is a no-op and can just write directly (assuming slice only contains \n)
-
- m_encodingBuffer.clear();
+ // We can do better here. On Linux, this is a no-op and can just write directly (assuming slice
+ // only contains \n)
+
+ m_encodingBuffer.clear();
StringBuilder sb;
#ifdef _WIN32
- const char newLine[] = "\r\n";
+ const char newLine[] = "\r\n";
#else
- const char newLine[] = "\n";
+ const char newLine[] = "\n";
#endif
const Index length = slice.getLength();
-
- for (Index i = 0; i < length; i++)
- {
- if (slice[i] == '\r')
- sb << newLine;
- else if (slice[i] == '\n')
- {
- if (i > 0 && slice[i - 1] != '\r')
- sb << newLine;
- }
- else
- sb << slice[i];
- }
-
- // NOTE! This assumes that sb contains *complete* utf8 code points, which it might not, as encoder is only able to handle complete code points.
+
+ for (Index i = 0; i < length; i++)
+ {
+ if (slice[i] == '\r')
+ sb << newLine;
+ else if (slice[i] == '\n')
+ {
+ if (i > 0 && slice[i - 1] != '\r')
+ sb << newLine;
+ }
+ else
+ sb << slice[i];
+ }
+
+ // NOTE! This assumes that sb contains *complete* utf8 code points, which it might not, as
+ // encoder is only able to handle complete code points.
m_encodingBuffer.clear();
- m_encoding->encode(sb.getUnownedSlice(), m_encodingBuffer);
- return m_stream->write(m_encodingBuffer.getBuffer(), m_encodingBuffer.getCount());
+ m_encoding->encode(sb.getUnownedSlice(), m_encodingBuffer);
+ return m_stream->write(m_encodingBuffer.getBuffer(), m_encodingBuffer.getCount());
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StreamReader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-StreamReader::StreamReader()
-{
-}
+StreamReader::StreamReader() {}
SlangResult StreamReader::init(const String& path)
{
@@ -81,12 +81,15 @@ SlangResult StreamReader::init(RefPtr<Stream> stream, CharEncoding* encoding)
{
m_stream = stream;
m_encoding = encoding;
- SLANG_RETURN_ON_FAIL(readBuffer());
+ SLANG_RETURN_ON_FAIL(readBuffer());
if (encoding == nullptr)
{
size_t offset;
- m_encodingType = CharEncoding::determineEncoding((const Byte*)m_buffer.getBuffer(), m_buffer.getCount(), offset);
+ m_encodingType = CharEncoding::determineEncoding(
+ (const Byte*)m_buffer.getBuffer(),
+ m_buffer.getCount(),
+ offset);
m_encoding = CharEncoding::getEncoding(m_encodingType);
m_index = Index(offset);
}
@@ -98,7 +101,7 @@ SlangResult StreamReader::init(RefPtr<Stream> stream, CharEncoding* encoding)
return SLANG_OK;
}
-
+
SlangResult StreamReader::readBuffer()
{
m_buffer.setCount(0);
@@ -109,7 +112,7 @@ SlangResult StreamReader::readBuffer()
return SLANG_OK;
}
- m_buffer.setCount(4096);
+ m_buffer.setCount(4096);
// TODO(JS): Not clear this is necessary
memset(m_buffer.getBuffer(), 0, m_buffer.getCount() * sizeof(m_buffer[0]));
@@ -117,46 +120,46 @@ SlangResult StreamReader::readBuffer()
size_t readBytes;
SLANG_RETURN_ON_FAIL(m_stream->read(m_buffer.getBuffer(), m_buffer.getCount(), readBytes));
- m_buffer.setCount(Index(readBytes));
- m_index = 0;
+ m_buffer.setCount(Index(readBytes));
+ m_index = 0;
return SLANG_OK;
}
char StreamReader::readBufferChar()
{
- if (m_index < m_buffer.getCount())
- {
- return m_buffer[m_index++];
- }
+ if (m_index < m_buffer.getCount())
+ {
+ return m_buffer[m_index++];
+ }
- readBuffer();
+ readBuffer();
if (m_index < m_buffer.getCount())
- {
- return m_buffer[m_index++];
- }
- return 0;
+ {
+ return m_buffer[m_index++];
+ }
+ return 0;
}
SlangResult StreamReader::readToEnd(String& outString)
{
- StringBuilder sb(16384);
- while (!isEnd())
- {
- auto ch = read();
- if (isEnd())
- break;
- if (ch == '\r')
- {
- sb.append('\n');
- if (peek() == '\n')
- read();
- }
- else
- sb.append(ch);
- }
-
- outString = sb.produceString();
+ StringBuilder sb(16384);
+ while (!isEnd())
+ {
+ auto ch = read();
+ if (isEnd())
+ break;
+ if (ch == '\r')
+ {
+ sb.append('\n');
+ if (peek() == '\n')
+ read();
+ }
+ else
+ sb.append(ch);
+ }
+
+ outString = sb.produceString();
return SLANG_OK;
}
diff --git a/source/core/slang-text-io.h b/source/core/slang-text-io.h
index 0ee381c46..7c13ebec8 100644
--- a/source/core/slang-text-io.h
+++ b/source/core/slang-text-io.h
@@ -1,9 +1,9 @@
#ifndef SLANG_CORE_TEXT_IO_H
#define SLANG_CORE_TEXT_IO_H
+#include "slang-char-encode.h"
#include "slang-secure-crt.h"
#include "slang-stream.h"
-#include "slang-char-encode.h"
namespace Slang
{
@@ -12,29 +12,29 @@ using Slang::_EndLine;
class TextReader
{
-public:
- virtual void close(){}
+public:
+ virtual void close() {}
virtual SlangResult readToEnd(String& outString) = 0;
- virtual bool isEnd() = 0;
-
- char read()
- {
- if (m_decodedCharIndex == m_decodedCharSize)
- readChar();
- if (m_decodedCharIndex < m_decodedCharSize)
- return m_decodedChar[m_decodedCharIndex++];
- else
- return 0;
- }
- char peek()
- {
- if (m_decodedCharIndex == m_decodedCharSize)
- readChar();
- if (m_decodedCharIndex < m_decodedCharSize)
- return m_decodedChar[m_decodedCharIndex];
- else
- return 0;
- }
+ virtual bool isEnd() = 0;
+
+ char read()
+ {
+ if (m_decodedCharIndex == m_decodedCharSize)
+ readChar();
+ if (m_decodedCharIndex < m_decodedCharSize)
+ return m_decodedChar[m_decodedCharIndex++];
+ else
+ return 0;
+ }
+ char peek()
+ {
+ if (m_decodedCharIndex == m_decodedCharSize)
+ readChar();
+ if (m_decodedCharIndex < m_decodedCharSize)
+ return m_decodedChar[m_decodedCharIndex];
+ else
+ return 0;
+ }
virtual ~TextReader() { close(); }
@@ -51,7 +51,10 @@ class StreamReader : public TextReader
{
public:
virtual SlangResult readToEnd(String& outString) SLANG_OVERRIDE;
- virtual bool isEnd() SLANG_OVERRIDE { return m_index == m_buffer.getCount() && m_stream->isEnd(); }
+ virtual bool isEnd() SLANG_OVERRIDE
+ {
+ return m_index == m_buffer.getCount() && m_stream->isEnd();
+ }
virtual void close() SLANG_OVERRIDE { m_stream->close(); }
void releaseStream() { m_stream.setNull(); }
@@ -69,24 +72,25 @@ protected:
Char32 codePoint = 0;
switch (m_encodingType)
{
- case CharEncodeType::UTF8:
+ case CharEncodeType::UTF8:
{
- codePoint = getUnicodePointFromUTF8([&]() -> Byte {return readBufferChar(); });
+ codePoint = getUnicodePointFromUTF8([&]() -> Byte { return readBufferChar(); });
break;
}
- case CharEncodeType::UTF16:
+ case CharEncodeType::UTF16:
{
- codePoint = getUnicodePointFromUTF16([&]() -> Byte {return readBufferChar(); });
+ codePoint = getUnicodePointFromUTF16([&]() -> Byte { return readBufferChar(); });
break;
}
- case CharEncodeType::UTF16Reversed:
+ case CharEncodeType::UTF16Reversed:
{
- codePoint = getUnicodePointFromUTF16Reversed([&]() -> Byte {return readBufferChar(); });
+ codePoint =
+ getUnicodePointFromUTF16Reversed([&]() -> Byte { return readBufferChar(); });
break;
}
- case CharEncodeType::UTF32:
+ case CharEncodeType::UTF32:
{
- codePoint = getUnicodePointFromUTF32([&]() -> Byte {return readBufferChar(); });
+ codePoint = getUnicodePointFromUTF32([&]() -> Byte { return readBufferChar(); });
break;
}
}
@@ -97,21 +101,20 @@ protected:
private:
char readBufferChar();
SlangResult readBuffer();
-
+
RefPtr<Stream> m_stream;
List<char> m_buffer;
CharEncodeType m_encodingType = CharEncodeType::UTF8;
CharEncoding* m_encoding = nullptr;
- Index m_index = 0; ///< Index into buffer
+ Index m_index = 0; ///< Index into buffer
};
class TextWriter
{
public:
-
- virtual SlangResult writeSlice(const UnownedStringSlice& slice) = 0;
- virtual void close(){}
+ virtual SlangResult writeSlice(const UnownedStringSlice& slice) = 0;
+ virtual void close() {}
SlangResult write(const UnownedStringSlice& slice) { return writeSlice(slice); }
SlangResult write(const char* str) { return writeSlice(UnownedStringSlice(str)); }
@@ -119,59 +122,59 @@ public:
virtual ~TextWriter() { close(); }
- template<typename T>
- TextWriter& operator << (const T& val)
- {
- write(val.ToString());
- return *this;
- }
- TextWriter& operator << (int value)
- {
- write(String(value));
- return *this;
- }
- TextWriter& operator << (float value)
- {
- write(String(value));
- return *this;
- }
- TextWriter& operator << (double value)
- {
- write(String(value));
- return *this;
- }
- TextWriter& operator << (const char* value)
- {
- writeSlice(UnownedStringSlice(value));
- return *this;
- }
- TextWriter& operator << (const String & val)
- {
- writeSlice(val.getUnownedSlice());
- return *this;
- }
- TextWriter& operator << (const _EndLine &)
- {
+ template<typename T>
+ TextWriter& operator<<(const T& val)
+ {
+ write(val.ToString());
+ return *this;
+ }
+ TextWriter& operator<<(int value)
+ {
+ write(String(value));
+ return *this;
+ }
+ TextWriter& operator<<(float value)
+ {
+ write(String(value));
+ return *this;
+ }
+ TextWriter& operator<<(double value)
+ {
+ write(String(value));
+ return *this;
+ }
+ TextWriter& operator<<(const char* value)
+ {
+ writeSlice(UnownedStringSlice(value));
+ return *this;
+ }
+ TextWriter& operator<<(const String& val)
+ {
+ writeSlice(val.getUnownedSlice());
+ return *this;
+ }
+ TextWriter& operator<<(const _EndLine&)
+ {
#ifdef _WIN32
- writeSlice(UnownedStringSlice::fromLiteral("\r\n"));
+ writeSlice(UnownedStringSlice::fromLiteral("\r\n"));
#else
- writeSlice(UnownedStringSlice::fromLiteral("\n"));
+ writeSlice(UnownedStringSlice::fromLiteral("\n"));
#endif
- return *this;
- }
+ return *this;
+ }
};
-
+
class StreamWriter : public TextWriter
{
public:
- // TextWriter
+ // TextWriter
virtual SlangResult writeSlice(const UnownedStringSlice& slice) SLANG_OVERRIDE;
virtual void close() SLANG_OVERRIDE { m_stream->close(); }
- void releaseStream() { m_stream.setNull(); }
+ void releaseStream() { m_stream.setNull(); }
StreamWriter() {}
-
+
SlangResult init(const String& path, CharEncoding* encoding = CharEncoding::UTF8);
SlangResult init(RefPtr<Stream> stream, CharEncoding* encoding = CharEncoding::UTF8);
@@ -181,6 +184,6 @@ private:
CharEncoding* m_encoding = nullptr;
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-token-reader.cpp b/source/core/slang-token-reader.cpp
index e8ebfb9ec..d37ee0ed4 100644
--- a/source/core/slang-token-reader.cpp
+++ b/source/core/slang-token-reader.cpp
@@ -1,462 +1,475 @@
#include "slang-token-reader.h"
-namespace Slang {
-namespace Misc {
+namespace Slang
+{
+namespace Misc
+{
- enum class TokenizeErrorType
- {
- InvalidCharacter, InvalidEscapeSequence
- };
+enum class TokenizeErrorType
+{
+ InvalidCharacter,
+ InvalidEscapeSequence
+};
- enum class State
- {
- Start, Identifier, Operator, Int, Hex, Fixed, Double, Char, String, MultiComment, SingleComment
- };
+enum class State
+{
+ Start,
+ Identifier,
+ Operator,
+ Int,
+ Hex,
+ Fixed,
+ Double,
+ Char,
+ String,
+ MultiComment,
+ SingleComment
+};
- enum class LexDerivative
- {
- None, Line, File
- };
+enum class LexDerivative
+{
+ None,
+ Line,
+ File
+};
- inline bool IsLetter(char ch)
- {
- return ((ch >= 'a' && ch <= 'z') ||
- (ch >= 'A' && ch <= 'Z') || ch == '_');
- }
+inline bool IsLetter(char ch)
+{
+ return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_');
+}
- inline bool IsDigit(char ch)
- {
- return ch >= '0' && ch <= '9';
- }
+inline bool IsDigit(char ch)
+{
+ return ch >= '0' && ch <= '9';
+}
- inline bool IsPunctuation(char ch)
- {
- return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%' ||
- ch == '!' || ch == '^' || ch == '&' || ch == '(' || ch == ')' ||
- ch == '=' || ch == '{' || ch == '}' || ch == '[' || ch == ']' ||
- ch == '|' || ch == ';' || ch == ',' || ch == '.' || ch == '<' ||
- ch == '>' || ch == '~' || ch == '@' || ch == ':' || ch == '?' || ch == '#';
- }
+inline bool IsPunctuation(char ch)
+{
+ return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%' || ch == '!' ||
+ ch == '^' || ch == '&' || ch == '(' || ch == ')' || ch == '=' || ch == '{' ||
+ ch == '}' || ch == '[' || ch == ']' || ch == '|' || ch == ';' || ch == ',' ||
+ ch == '.' || ch == '<' || ch == '>' || ch == '~' || ch == '@' || ch == ':' ||
+ ch == '?' || ch == '#';
+}
- inline bool IsWhiteSpace(char ch)
- {
- return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v');
- }
+inline bool IsWhiteSpace(char ch)
+{
+ return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v');
+}
- void ParseOperators(const String & str, List<Token> & tokens, TokenFlags& tokenFlags, int line, int col, int startPos, String fileName)
+void ParseOperators(
+ const String& str,
+ List<Token>& tokens,
+ TokenFlags& tokenFlags,
+ int line,
+ int col,
+ int startPos,
+ String fileName)
+{
+ Index pos = 0;
+ while (pos < str.getLength())
{
- Index pos = 0;
- while (pos < str.getLength())
+ wchar_t curChar = str[pos];
+ wchar_t nextChar = (pos < str.getLength() - 1) ? str[pos + 1] : '\0';
+ wchar_t nextNextChar = (pos < str.getLength() - 2) ? str[pos + 2] : '\0';
+ auto InsertToken = [&](TokenType type, const String& ct)
{
- wchar_t curChar = str[pos];
- wchar_t nextChar = (pos < str.getLength() - 1) ? str[pos + 1] : '\0';
- wchar_t nextNextChar = (pos < str.getLength() - 2) ? str[pos + 2] : '\0';
- auto InsertToken = [&](TokenType type, const String & ct)
- {
- tokens.add(Token(type, ct, line, int(col + pos), int(pos + startPos), fileName, tokenFlags));
- tokenFlags = 0;
- };
- switch (curChar)
- {
- case '+':
- if (nextChar == '+')
- {
- InsertToken(TokenType::OpInc, "++");
- pos += 2;
- }
- else if (nextChar == '=')
- {
- InsertToken(TokenType::OpAddAssign, "+=");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpAdd, "+");
- pos++;
- }
- break;
- case '-':
- if (nextChar == '-')
- {
- InsertToken(TokenType::OpDec, "--");
- pos += 2;
- }
- else if (nextChar == '=')
- {
- InsertToken(TokenType::OpSubAssign, "-=");
- pos += 2;
- }
- else if (nextChar == '>')
- {
- InsertToken(TokenType::RightArrow, "->");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpSub, "-");
- pos++;
- }
- break;
- case '*':
- if (nextChar == '=')
- {
- InsertToken(TokenType::OpMulAssign, "*=");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpMul, "*");
- pos++;
- }
- break;
- case '/':
- if (nextChar == '=')
- {
- InsertToken(TokenType::OpDivAssign, "/=");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpDiv, "/");
- pos++;
- }
- break;
- case '%':
- if (nextChar == '=')
- {
- InsertToken(TokenType::OpModAssign, "%=");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpMod, "%");
- pos++;
- }
- break;
- case '|':
- if (nextChar == '|')
- {
- InsertToken(TokenType::OpOr, "||");
- pos += 2;
- }
- else if (nextChar == '=')
- {
- InsertToken(TokenType::OpOrAssign, "|=");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpBitOr, "|");
- pos++;
- }
- break;
- case '&':
- if (nextChar == '&')
- {
- InsertToken(TokenType::OpAnd, "&&");
- pos += 2;
- }
- else if (nextChar == '=')
- {
- InsertToken(TokenType::OpAndAssign, "&=");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpBitAnd, "&");
- pos++;
- }
- break;
- case '^':
- if (nextChar == '=')
- {
- InsertToken(TokenType::OpXorAssign, "^=");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpBitXor, "^");
- pos++;
- }
- break;
- case '>':
- if (nextChar == '>')
- {
- if (nextNextChar == '=')
- {
- InsertToken(TokenType::OpShrAssign, ">>=");
- pos += 3;
- }
- else
- {
- InsertToken(TokenType::OpRsh, ">>");
- pos += 2;
- }
- }
- else if (nextChar == '=')
- {
- InsertToken(TokenType::OpGeq, ">=");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpGreater, ">");
- pos++;
- }
- break;
- case '<':
- if (nextChar == '<')
- {
- if (nextNextChar == '=')
- {
- InsertToken(TokenType::OpShlAssign, "<<=");
- pos += 3;
- }
- else
- {
- InsertToken(TokenType::OpLsh, "<<");
- pos += 2;
- }
- }
- else if (nextChar == '=')
- {
- InsertToken(TokenType::OpLeq, "<=");
- pos += 2;
- }
- else
- {
- InsertToken(TokenType::OpLess, "<");
- pos++;
- }
- break;
- case '=':
- if (nextChar == '=')
+ tokens.add(
+ Token(type, ct, line, int(col + pos), int(pos + startPos), fileName, tokenFlags));
+ tokenFlags = 0;
+ };
+ switch (curChar)
+ {
+ case '+':
+ if (nextChar == '+')
+ {
+ InsertToken(TokenType::OpInc, "++");
+ pos += 2;
+ }
+ else if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpAddAssign, "+=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpAdd, "+");
+ pos++;
+ }
+ break;
+ case '-':
+ if (nextChar == '-')
+ {
+ InsertToken(TokenType::OpDec, "--");
+ pos += 2;
+ }
+ else if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpSubAssign, "-=");
+ pos += 2;
+ }
+ else if (nextChar == '>')
+ {
+ InsertToken(TokenType::RightArrow, "->");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpSub, "-");
+ pos++;
+ }
+ break;
+ case '*':
+ if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpMulAssign, "*=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpMul, "*");
+ pos++;
+ }
+ break;
+ case '/':
+ if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpDivAssign, "/=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpDiv, "/");
+ pos++;
+ }
+ break;
+ case '%':
+ if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpModAssign, "%=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpMod, "%");
+ pos++;
+ }
+ break;
+ case '|':
+ if (nextChar == '|')
+ {
+ InsertToken(TokenType::OpOr, "||");
+ pos += 2;
+ }
+ else if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpOrAssign, "|=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpBitOr, "|");
+ pos++;
+ }
+ break;
+ case '&':
+ if (nextChar == '&')
+ {
+ InsertToken(TokenType::OpAnd, "&&");
+ pos += 2;
+ }
+ else if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpAndAssign, "&=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpBitAnd, "&");
+ pos++;
+ }
+ break;
+ case '^':
+ if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpXorAssign, "^=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpBitXor, "^");
+ pos++;
+ }
+ break;
+ case '>':
+ if (nextChar == '>')
+ {
+ if (nextNextChar == '=')
{
- InsertToken(TokenType::OpEql, "==");
- pos += 2;
+ InsertToken(TokenType::OpShrAssign, ">>=");
+ pos += 3;
}
else
{
- InsertToken(TokenType::OpAssign, "=");
- pos++;
- }
- break;
- case '!':
- if (nextChar == '=')
- {
- InsertToken(TokenType::OpNeq, "!=");
+ InsertToken(TokenType::OpRsh, ">>");
pos += 2;
}
- else
- {
- InsertToken(TokenType::OpNot, "!");
- pos++;
- }
- break;
- case '?':
- InsertToken(TokenType::QuestionMark, "?");
- pos++;
- break;
- case '@':
- InsertToken(TokenType::At, "@");
+ }
+ else if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpGeq, ">=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpGreater, ">");
pos++;
- break;
- case '#':
- if (nextChar == '#')
+ }
+ break;
+ case '<':
+ if (nextChar == '<')
+ {
+ if (nextNextChar == '=')
{
- InsertToken(TokenType::PoundPound, "##");
- pos += 2;
+ InsertToken(TokenType::OpShlAssign, "<<=");
+ pos += 3;
}
else
{
- InsertToken(TokenType::Pound, "#");
- pos++;
+ InsertToken(TokenType::OpLsh, "<<");
+ pos += 2;
}
+ }
+ else if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpLeq, "<=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpLess, "<");
pos++;
- break;
- case ':':
- InsertToken(TokenType::Colon, ":");
- pos++;
- break;
- case '~':
- InsertToken(TokenType::OpBitNot, "~");
- pos++;
- break;
- case ';':
- InsertToken(TokenType::Semicolon, ";");
- pos++;
- break;
- case ',':
- InsertToken(TokenType::Comma, ",");
- pos++;
- break;
- case '.':
- InsertToken(TokenType::Dot, ".");
- pos++;
- break;
- case '{':
- InsertToken(TokenType::LBrace, "{");
- pos++;
- break;
- case '}':
- InsertToken(TokenType::RBrace, "}");
- pos++;
- break;
- case '[':
- InsertToken(TokenType::LBracket, "[");
- pos++;
- break;
- case ']':
- InsertToken(TokenType::RBracket, "]");
+ }
+ break;
+ case '=':
+ if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpEql, "==");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpAssign, "=");
pos++;
- break;
- case '(':
- InsertToken(TokenType::LParent, "(");
+ }
+ break;
+ case '!':
+ if (nextChar == '=')
+ {
+ InsertToken(TokenType::OpNeq, "!=");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::OpNot, "!");
pos++;
- break;
- case ')':
- InsertToken(TokenType::RParent, ")");
+ }
+ break;
+ case '?':
+ InsertToken(TokenType::QuestionMark, "?");
+ pos++;
+ break;
+ case '@':
+ InsertToken(TokenType::At, "@");
+ pos++;
+ break;
+ case '#':
+ if (nextChar == '#')
+ {
+ InsertToken(TokenType::PoundPound, "##");
+ pos += 2;
+ }
+ else
+ {
+ InsertToken(TokenType::Pound, "#");
pos++;
- break;
}
+ pos++;
+ break;
+ case ':':
+ InsertToken(TokenType::Colon, ":");
+ pos++;
+ break;
+ case '~':
+ InsertToken(TokenType::OpBitNot, "~");
+ pos++;
+ break;
+ case ';':
+ InsertToken(TokenType::Semicolon, ";");
+ pos++;
+ break;
+ case ',':
+ InsertToken(TokenType::Comma, ",");
+ pos++;
+ break;
+ case '.':
+ InsertToken(TokenType::Dot, ".");
+ pos++;
+ break;
+ case '{':
+ InsertToken(TokenType::LBrace, "{");
+ pos++;
+ break;
+ case '}':
+ InsertToken(TokenType::RBrace, "}");
+ pos++;
+ break;
+ case '[':
+ InsertToken(TokenType::LBracket, "[");
+ pos++;
+ break;
+ case ']':
+ InsertToken(TokenType::RBracket, "]");
+ pos++;
+ break;
+ case '(':
+ InsertToken(TokenType::LParent, "(");
+ pos++;
+ break;
+ case ')':
+ InsertToken(TokenType::RParent, ")");
+ pos++;
+ break;
}
}
+}
- List<Token> TokenizeText(const String & fileName, const String & text)
+List<Token> TokenizeText(const String& fileName, const String& text)
+{
+ Index lastPos = 0, pos = 0;
+ int line = 1, col = 0;
+ String file = fileName;
+ State state = State::Start;
+ StringBuilder tokenBuilder;
+ int tokenLine, tokenCol;
+ List<Token> tokenList;
+ LexDerivative derivative = LexDerivative::None;
+ TokenFlags tokenFlags = TokenFlag::AtStartOfLine;
+ auto InsertToken = [&](TokenType type)
+ {
+ derivative = LexDerivative::None;
+ tokenList.add(
+ Token(type, tokenBuilder.toString(), tokenLine, tokenCol, int(pos), file, tokenFlags));
+ tokenFlags = 0;
+ tokenBuilder.clear();
+ };
+ auto ProcessTransferChar = [&](char nextChar)
{
- Index lastPos = 0, pos = 0;
- int line = 1, col = 0;
- String file = fileName;
- State state = State::Start;
- StringBuilder tokenBuilder;
- int tokenLine, tokenCol;
- List<Token> tokenList;
- LexDerivative derivative = LexDerivative::None;
- TokenFlags tokenFlags = TokenFlag::AtStartOfLine;
- auto InsertToken = [&](TokenType type)
+ switch (nextChar)
{
- derivative = LexDerivative::None;
- tokenList.add(Token(type, tokenBuilder.toString(), tokenLine, tokenCol, int(pos), file, tokenFlags));
- tokenFlags = 0;
- tokenBuilder.clear();
- };
- auto ProcessTransferChar = [&](char nextChar)
+ case '\\':
+ case '\"':
+ case '\'': tokenBuilder.append(nextChar); break;
+ case 't': tokenBuilder.append('\t'); break;
+ case 's': tokenBuilder.append(' '); break;
+ case 'n': tokenBuilder.append('\n'); break;
+ case 'r': tokenBuilder.append('\r'); break;
+ case 'b': tokenBuilder.append('\b'); break;
+ }
+ };
+ while (pos <= text.getLength())
+ {
+ char curChar = (pos < text.getLength() ? text[pos] : ' ');
+ char nextChar = (pos < text.getLength() - 1) ? text[pos + 1] : '\0';
+ if (lastPos != pos)
{
- switch (nextChar)
- {
- case '\\':
- case '\"':
- case '\'':
- tokenBuilder.append(nextChar);
- break;
- case 't':
- tokenBuilder.append('\t');
- break;
- case 's':
- tokenBuilder.append(' ');
- break;
- case 'n':
- tokenBuilder.append('\n');
- break;
- case 'r':
- tokenBuilder.append('\r');
- break;
- case 'b':
- tokenBuilder.append('\b');
- break;
+ if (curChar == '\n')
+ {
+ line++;
+ col = 0;
}
- };
- while (pos <= text.getLength())
+ else
+ col++;
+ lastPos = pos;
+ }
+
+ switch (state)
{
- char curChar = (pos < text.getLength() ? text[pos] : ' ');
- char nextChar = (pos < text.getLength() - 1) ? text[pos + 1] : '\0';
- if (lastPos != pos)
+ case State::Start:
+ if (IsLetter(curChar))
{
- if (curChar == '\n')
- {
- line++;
- col = 0;
- }
- else
- col++;
- lastPos = pos;
+ state = State::Identifier;
+ tokenLine = line;
+ tokenCol = col;
}
-
- switch (state)
+ else if (IsDigit(curChar))
{
- case State::Start:
- if (IsLetter(curChar))
- {
- state = State::Identifier;
- tokenLine = line;
- tokenCol = col;
- }
- else if (IsDigit(curChar))
- {
- state = State::Int;
- tokenLine = line;
- tokenCol = col;
- }
- else if (curChar == '\'')
- {
- state = State::Char;
- pos++;
- tokenLine = line;
- tokenCol = col;
- }
- else if (curChar == '"')
- {
- state = State::String;
- pos++;
- tokenLine = line;
- tokenCol = col;
- }
- else if (curChar == '\r' || curChar == '\n')
- {
- tokenFlags |= TokenFlag::AtStartOfLine | TokenFlag::AfterWhitespace;
- pos++;
- }
- else if (curChar == ' ' || curChar == '\t' || curChar == '\xC2' || curChar == '\xA0') // -62/-96:non-break space
- {
- tokenFlags |= TokenFlag::AfterWhitespace;
- pos++;
- }
- else if (curChar == '/' && nextChar == '/')
- {
- state = State::SingleComment;
- pos += 2;
- }
- else if (curChar == '/' && nextChar == '*')
- {
- pos += 2;
- state = State::MultiComment;
- }
- else if (curChar == '.' && IsDigit(nextChar))
- {
- tokenBuilder.append("0.");
- state = State::Fixed;
- pos++;
- }
- else if (IsPunctuation(curChar))
- {
- state = State::Operator;
- tokenLine = line;
- tokenCol = col;
- }
- else
- {
- pos++;
- }
- break;
- case State::Identifier:
- if (IsLetter(curChar) || IsDigit(curChar))
- {
- tokenBuilder.append(curChar);
- pos++;
- }
- else
- {
- auto tokenStr = tokenBuilder.toString();
+ state = State::Int;
+ tokenLine = line;
+ tokenCol = col;
+ }
+ else if (curChar == '\'')
+ {
+ state = State::Char;
+ pos++;
+ tokenLine = line;
+ tokenCol = col;
+ }
+ else if (curChar == '"')
+ {
+ state = State::String;
+ pos++;
+ tokenLine = line;
+ tokenCol = col;
+ }
+ else if (curChar == '\r' || curChar == '\n')
+ {
+ tokenFlags |= TokenFlag::AtStartOfLine | TokenFlag::AfterWhitespace;
+ pos++;
+ }
+ else if (
+ curChar == ' ' || curChar == '\t' || curChar == '\xC2' ||
+ curChar == '\xA0') // -62/-96:non-break space
+ {
+ tokenFlags |= TokenFlag::AfterWhitespace;
+ pos++;
+ }
+ else if (curChar == '/' && nextChar == '/')
+ {
+ state = State::SingleComment;
+ pos += 2;
+ }
+ else if (curChar == '/' && nextChar == '*')
+ {
+ pos += 2;
+ state = State::MultiComment;
+ }
+ else if (curChar == '.' && IsDigit(nextChar))
+ {
+ tokenBuilder.append("0.");
+ state = State::Fixed;
+ pos++;
+ }
+ else if (IsPunctuation(curChar))
+ {
+ state = State::Operator;
+ tokenLine = line;
+ tokenCol = col;
+ }
+ else
+ {
+ pos++;
+ }
+ break;
+ case State::Identifier:
+ if (IsLetter(curChar) || IsDigit(curChar))
+ {
+ tokenBuilder.append(curChar);
+ pos++;
+ }
+ else
+ {
+ auto tokenStr = tokenBuilder.toString();
#if 0
if (tokenStr == "#line_reset#")
{
@@ -478,204 +491,213 @@ namespace Misc {
}
else
#endif
- InsertToken(TokenType::Identifier);
- state = State::Start;
- }
- break;
- case State::Operator:
- if (IsPunctuation(curChar) && !((curChar == '/' && nextChar == '/') || (curChar == '/' && nextChar == '*')))
+ InsertToken(TokenType::Identifier);
+ state = State::Start;
+ }
+ break;
+ case State::Operator:
+ if (IsPunctuation(curChar) &&
+ !((curChar == '/' && nextChar == '/') || (curChar == '/' && nextChar == '*')))
+ {
+ tokenBuilder.append(curChar);
+ pos++;
+ }
+ else
+ {
+ // do token analyze
+ ParseOperators(
+ tokenBuilder.toString(),
+ tokenList,
+ tokenFlags,
+ tokenLine,
+ tokenCol,
+ (int)(pos - tokenBuilder.getLength()),
+ file);
+ tokenBuilder.clear();
+ state = State::Start;
+ }
+ break;
+ case State::Int:
+ if (IsDigit(curChar))
+ {
+ tokenBuilder.append(curChar);
+ pos++;
+ }
+ else if (curChar == '.')
+ {
+ state = State::Fixed;
+ tokenBuilder.append(curChar);
+ pos++;
+ }
+ else if (curChar == 'e' || curChar == 'E')
+ {
+ state = State::Double;
+ tokenBuilder.append(curChar);
+ if (nextChar == '-' || nextChar == '+')
{
- tokenBuilder.append(curChar);
+ tokenBuilder.append(nextChar);
pos++;
}
- else
+ pos++;
+ }
+ else if (curChar == 'x')
+ {
+ state = State::Hex;
+ tokenBuilder.append(curChar);
+ pos++;
+ }
+ else if (curChar == 'u')
+ {
+ pos++;
+ tokenBuilder.append(curChar);
+ InsertToken(TokenType::IntLiteral);
+ state = State::Start;
+ }
+ else
+ {
+ if (derivative == LexDerivative::Line)
{
- //do token analyze
- ParseOperators(tokenBuilder.toString(), tokenList, tokenFlags, tokenLine, tokenCol, (int)(pos - tokenBuilder.getLength()), file);
+ derivative = LexDerivative::None;
+ line = stringToInt(tokenBuilder.toString()) - 1;
+ col = 0;
tokenBuilder.clear();
- state = State::Start;
- }
- break;
- case State::Int:
- if (IsDigit(curChar))
- {
- tokenBuilder.append(curChar);
- pos++;
}
- else if (curChar == '.')
+ else
{
- state = State::Fixed;
- tokenBuilder.append(curChar);
- pos++;
+ InsertToken(TokenType::IntLiteral);
}
- else if (curChar == 'e' || curChar == 'E')
+ state = State::Start;
+ }
+ break;
+ case State::Hex:
+ if (IsDigit(curChar) || (curChar >= 'a' && curChar <= 'f') ||
+ (curChar >= 'A' && curChar <= 'F'))
+ {
+ tokenBuilder.append(curChar);
+ pos++;
+ }
+ else
+ {
+ InsertToken(TokenType::IntLiteral);
+ state = State::Start;
+ }
+ break;
+ case State::Fixed:
+ if (IsDigit(curChar))
+ {
+ tokenBuilder.append(curChar);
+ pos++;
+ }
+ else if (curChar == 'e' || curChar == 'E')
+ {
+ state = State::Double;
+ tokenBuilder.append(curChar);
+ if (nextChar == '-' || nextChar == '+')
{
- state = State::Double;
- tokenBuilder.append(curChar);
- if (nextChar == '-' || nextChar == '+')
- {
- tokenBuilder.append(nextChar);
- pos++;
- }
+ tokenBuilder.append(nextChar);
pos++;
}
- else if (curChar == 'x')
- {
- state = State::Hex;
- tokenBuilder.append(curChar);
+ pos++;
+ }
+ else
+ {
+ if (curChar == 'f')
pos++;
- }
- else if (curChar == 'u')
- {
+ InsertToken(TokenType::DoubleLiteral);
+ state = State::Start;
+ }
+ break;
+ case State::Double:
+ if (IsDigit(curChar))
+ {
+ tokenBuilder.append(curChar);
+ pos++;
+ }
+ else
+ {
+ if (curChar == 'f')
pos++;
- tokenBuilder.append(curChar);
- InsertToken(TokenType::IntLiteral);
- state = State::Start;
- }
- else
- {
- if (derivative == LexDerivative::Line)
- {
- derivative = LexDerivative::None;
- line = stringToInt(tokenBuilder.toString()) - 1;
- col = 0;
- tokenBuilder.clear();
- }
- else
- {
- InsertToken(TokenType::IntLiteral);
- }
- state = State::Start;
- }
- break;
- case State::Hex:
- if (IsDigit(curChar) || (curChar >= 'a' && curChar <= 'f') || (curChar >= 'A' && curChar <= 'F'))
+ InsertToken(TokenType::DoubleLiteral);
+ state = State::Start;
+ }
+ break;
+ case State::String:
+ if (curChar != '"')
+ {
+ if (curChar == '\\')
{
- tokenBuilder.append(curChar);
+ ProcessTransferChar(nextChar);
pos++;
}
else
- {
- InsertToken(TokenType::IntLiteral);
- state = State::Start;
- }
- break;
- case State::Fixed:
- if (IsDigit(curChar))
- {
tokenBuilder.append(curChar);
- pos++;
- }
- else if (curChar == 'e' || curChar == 'E')
+ }
+ else
+ {
+ if (derivative == LexDerivative::File)
{
- state = State::Double;
- tokenBuilder.append(curChar);
- if (nextChar == '-' || nextChar == '+')
- {
- tokenBuilder.append(nextChar);
- pos++;
- }
- pos++;
+ derivative = LexDerivative::None;
+ file = tokenBuilder.toString();
+ tokenBuilder.clear();
}
else
{
- if (curChar == 'f')
- pos++;
- InsertToken(TokenType::DoubleLiteral);
- state = State::Start;
+ InsertToken(TokenType::StringLiteral);
}
- break;
- case State::Double:
- if (IsDigit(curChar))
+ state = State::Start;
+ }
+ pos++;
+ break;
+ case State::Char:
+ if (curChar != '\'')
+ {
+ if (curChar == '\\')
{
- tokenBuilder.append(curChar);
+ ProcessTransferChar(nextChar);
pos++;
}
else
- {
- if (curChar == 'f')
- pos++;
- InsertToken(TokenType::DoubleLiteral);
- state = State::Start;
- }
- break;
- case State::String:
- if (curChar != '"')
- {
- if (curChar == '\\')
- {
- ProcessTransferChar(nextChar);
- pos++;
- }
- else
- tokenBuilder.append(curChar);
- }
- else
- {
- if (derivative == LexDerivative::File)
- {
- derivative = LexDerivative::None;
- file = tokenBuilder.toString();
- tokenBuilder.clear();
- }
- else
- {
- InsertToken(TokenType::StringLiteral);
- }
- state = State::Start;
- }
- pos++;
- break;
- case State::Char:
- if (curChar != '\'')
- {
- if (curChar == '\\')
- {
- ProcessTransferChar(nextChar);
- pos++;
- }
- else
- tokenBuilder.append(curChar);
- }
- else
- {
- InsertToken(TokenType::CharLiteral);
- state = State::Start;
- }
- pos++;
- break;
- case State::SingleComment:
- if (curChar == '\n')
- {
- state = State::Start;
- tokenFlags |= TokenFlag::AtStartOfLine | TokenFlag::AfterWhitespace;
- }
- pos++;
- break;
- case State::MultiComment:
- if (curChar == '*' && nextChar == '/')
- {
- state = State::Start;
- tokenFlags |= TokenFlag::AfterWhitespace;
- pos += 2;
- }
- else
- pos++;
- break;
+ tokenBuilder.append(curChar);
+ }
+ else
+ {
+ InsertToken(TokenType::CharLiteral);
+ state = State::Start;
}
+ pos++;
+ break;
+ case State::SingleComment:
+ if (curChar == '\n')
+ {
+ state = State::Start;
+ tokenFlags |= TokenFlag::AtStartOfLine | TokenFlag::AfterWhitespace;
+ }
+ pos++;
+ break;
+ case State::MultiComment:
+ if (curChar == '*' && nextChar == '/')
+ {
+ state = State::Start;
+ tokenFlags |= TokenFlag::AfterWhitespace;
+ pos += 2;
+ }
+ else
+ pos++;
+ break;
}
- return tokenList;
- }
- List<Token> TokenizeText(const String & text)
- {
- return TokenizeText("", text);
}
+ return tokenList;
+}
+List<Token> TokenizeText(const String& text)
+{
+ return TokenizeText("", text);
+}
- TokenReader::TokenReader(String text)
- {
- this->tokens = TokenizeText("", text);
- tokenPtr = 0;
- }
+TokenReader::TokenReader(String text)
+{
+ this->tokens = TokenizeText("", text);
+ tokenPtr = 0;
+}
} // namespace Misc
} // namespace Slang
diff --git a/source/core/slang-token-reader.h b/source/core/slang-token-reader.h
index c4b552d29..41affb1d0 100644
--- a/source/core/slang-token-reader.h
+++ b/source/core/slang-token-reader.h
@@ -3,306 +3,351 @@
#include "slang-basic.h"
-namespace Slang {
-namespace Misc {
+namespace Slang
+{
+namespace Misc
+{
- /* NOTE! This TokenReader is NOT used by the main slang compiler !*/
+/* NOTE! This TokenReader is NOT used by the main slang compiler !*/
- enum class TokenType
- {
- EndOfFile = -1,
- // illegal
- Unknown,
- // identifier
- Identifier,
- // constant
- IntLiteral, DoubleLiteral, StringLiteral, CharLiteral,
- // operators
- Semicolon, Comma, Dot, LBrace, RBrace, LBracket, RBracket, LParent, RParent,
- OpAssign, OpAdd, OpSub, OpMul, OpDiv, OpMod, OpNot, OpBitNot, OpLsh, OpRsh,
- OpEql, OpNeq, OpGreater, OpLess, OpGeq, OpLeq,
- OpAnd, OpOr, OpBitXor, OpBitAnd, OpBitOr,
- OpInc, OpDec, OpAddAssign, OpSubAssign, OpMulAssign, OpDivAssign, OpModAssign,
- OpShlAssign, OpShrAssign, OpOrAssign, OpAndAssign, OpXorAssign,
+enum class TokenType
+{
+ EndOfFile = -1,
+ // illegal
+ Unknown,
+ // identifier
+ Identifier,
+ // constant
+ IntLiteral,
+ DoubleLiteral,
+ StringLiteral,
+ CharLiteral,
+ // operators
+ Semicolon,
+ Comma,
+ Dot,
+ LBrace,
+ RBrace,
+ LBracket,
+ RBracket,
+ LParent,
+ RParent,
+ OpAssign,
+ OpAdd,
+ OpSub,
+ OpMul,
+ OpDiv,
+ OpMod,
+ OpNot,
+ OpBitNot,
+ OpLsh,
+ OpRsh,
+ OpEql,
+ OpNeq,
+ OpGreater,
+ OpLess,
+ OpGeq,
+ OpLeq,
+ OpAnd,
+ OpOr,
+ OpBitXor,
+ OpBitAnd,
+ OpBitOr,
+ OpInc,
+ OpDec,
+ OpAddAssign,
+ OpSubAssign,
+ OpMulAssign,
+ OpDivAssign,
+ OpModAssign,
+ OpShlAssign,
+ OpShrAssign,
+ OpOrAssign,
+ OpAndAssign,
+ OpXorAssign,
- QuestionMark, Colon, RightArrow, At, Pound, PoundPound, Scope,
- };
+ QuestionMark,
+ Colon,
+ RightArrow,
+ At,
+ Pound,
+ PoundPound,
+ Scope,
+};
- class CodePosition
+class CodePosition
+{
+public:
+ int Line = -1, Col = -1, Pos = -1;
+ String FileName;
+ String ToString()
{
- public:
- int Line = -1, Col = -1, Pos = -1;
- String FileName;
- String ToString()
- {
- StringBuilder sb(100);
- sb << FileName;
- if (Line != -1)
- sb << "(" << Line << ")";
- return sb.produceString();
- }
- CodePosition() = default;
- CodePosition(int line, int col, int pos, String fileName)
- {
- Line = line;
- Col = col;
- Pos = pos;
- this->FileName = fileName;
- }
- bool operator < (const CodePosition & pos) const
- {
- return FileName < pos.FileName || (FileName == pos.FileName && Line < pos.Line) ||
- (FileName == pos.FileName && Line == pos.Line && Col < pos.Col);
- }
- bool operator == (const CodePosition & pos) const
- {
- return FileName == pos.FileName && Line == pos.Line && Col == pos.Col;
- }
- };
-
- enum TokenFlag : unsigned int
+ StringBuilder sb(100);
+ sb << FileName;
+ if (Line != -1)
+ sb << "(" << Line << ")";
+ return sb.produceString();
+ }
+ CodePosition() = default;
+ CodePosition(int line, int col, int pos, String fileName)
+ {
+ Line = line;
+ Col = col;
+ Pos = pos;
+ this->FileName = fileName;
+ }
+ bool operator<(const CodePosition& pos) const
+ {
+ return FileName < pos.FileName || (FileName == pos.FileName && Line < pos.Line) ||
+ (FileName == pos.FileName && Line == pos.Line && Col < pos.Col);
+ }
+ bool operator==(const CodePosition& pos) const
{
- AtStartOfLine = 1 << 0,
- AfterWhitespace = 1 << 1,
- };
- typedef unsigned int TokenFlags;
+ return FileName == pos.FileName && Line == pos.Line && Col == pos.Col;
+ }
+};
- class Token
+enum TokenFlag : unsigned int
+{
+ AtStartOfLine = 1 << 0,
+ AfterWhitespace = 1 << 1,
+};
+typedef unsigned int TokenFlags;
+
+class Token
+{
+public:
+ TokenType Type = TokenType::Unknown;
+ String Content;
+ CodePosition Position;
+ TokenFlags flags = 0;
+ Token() = default;
+ Token(
+ TokenType type,
+ const String& content,
+ int line,
+ int col,
+ int pos,
+ String fileName,
+ TokenFlags flags = 0)
+ : flags(flags)
{
- public:
- TokenType Type = TokenType::Unknown;
- String Content;
- CodePosition Position;
- TokenFlags flags = 0;
- Token() = default;
- Token(TokenType type, const String & content, int line, int col, int pos, String fileName, TokenFlags flags = 0)
- : flags(flags)
- {
- Type = type;
- Content = content;
- Position = CodePosition(line, col, pos, fileName);
- }
- };
+ Type = type;
+ Content = content;
+ Position = CodePosition(line, col, pos, fileName);
+ }
+};
- class TextFormatException : public Exception
+class TextFormatException : public Exception
+{
+public:
+ TextFormatException(String message)
+ : Exception(message)
{
- public:
- TextFormatException(String message)
- : Exception(message)
- {}
- };
+ }
+};
+
+class TokenReader
+{
+private:
+ bool legal;
+ List<Token> tokens;
+ int tokenPtr;
- class TokenReader
+public:
+ TokenReader(String text);
+ int ReadInt()
{
- private:
- bool legal;
- List<Token> tokens;
- int tokenPtr;
- public:
- TokenReader(String text);
- int ReadInt()
+ auto token = ReadToken();
+ bool neg = false;
+ if (token.Content.getUnownedSlice().isChar('-'))
{
- auto token = ReadToken();
- bool neg = false;
- if (token.Content.getUnownedSlice().isChar('-'))
- {
- neg = true;
- token = ReadToken();
- }
- if (token.Type == TokenType::IntLiteral)
- {
- if (neg)
- return -stringToInt(token.Content);
- else
- return stringToInt(token.Content);
- }
- throw TextFormatException("Text parsing error: int expected.");
+ neg = true;
+ token = ReadToken();
}
- unsigned int ReadUInt()
+ if (token.Type == TokenType::IntLiteral)
{
- auto token = ReadToken();
- if (token.Type == TokenType::IntLiteral)
- {
- return stringToUInt(token.Content);
- }
- throw TextFormatException("Text parsing error: int expected.");
+ if (neg)
+ return -stringToInt(token.Content);
+ else
+ return stringToInt(token.Content);
}
- double ReadDouble()
+ throw TextFormatException("Text parsing error: int expected.");
+ }
+ unsigned int ReadUInt()
+ {
+ auto token = ReadToken();
+ if (token.Type == TokenType::IntLiteral)
{
- auto token = ReadToken();
- bool neg = false;
- if (token.Content.getUnownedSlice().isChar('-'))
- {
- neg = true;
- token = ReadToken();
- }
- if (token.Type == TokenType::DoubleLiteral || token.Type == TokenType::IntLiteral)
- {
- if (neg)
- return -stringToDouble(token.Content);
- else
- return stringToDouble(token.Content);
- }
- throw TextFormatException("Text parsing error: floating point value expected.");
+ return stringToUInt(token.Content);
}
- float ReadFloat()
+ throw TextFormatException("Text parsing error: int expected.");
+ }
+ double ReadDouble()
+ {
+ auto token = ReadToken();
+ bool neg = false;
+ if (token.Content.getUnownedSlice().isChar('-'))
{
- return (float)ReadDouble();
+ neg = true;
+ token = ReadToken();
}
- String ReadWord()
+ if (token.Type == TokenType::DoubleLiteral || token.Type == TokenType::IntLiteral)
{
- auto token = ReadToken();
- if (token.Type == TokenType::Identifier)
- {
- return token.Content;
- }
- throw TextFormatException("Text parsing error: identifier expected.");
+ if (neg)
+ return -stringToDouble(token.Content);
+ else
+ return stringToDouble(token.Content);
}
- String Read(const char * expectedStr)
+ throw TextFormatException("Text parsing error: floating point value expected.");
+ }
+ float ReadFloat() { return (float)ReadDouble(); }
+ String ReadWord()
+ {
+ auto token = ReadToken();
+ if (token.Type == TokenType::Identifier)
{
- auto token = ReadToken();
- if (token.Content == expectedStr)
- {
- return token.Content;
- }
- throw TextFormatException("Text parsing error: \'" + String(expectedStr) + "\' expected.");
+ return token.Content;
}
- String Read(String expectedStr)
+ throw TextFormatException("Text parsing error: identifier expected.");
+ }
+ String Read(const char* expectedStr)
+ {
+ auto token = ReadToken();
+ if (token.Content == expectedStr)
{
- auto token = ReadToken();
- if (token.Content == expectedStr)
- {
- return token.Content;
- }
- throw TextFormatException("Text parsing error: \'" + expectedStr + "\' expected.");
+ return token.Content;
}
- bool Read(TokenType tokenType)
+ throw TextFormatException("Text parsing error: \'" + String(expectedStr) + "\' expected.");
+ }
+ String Read(String expectedStr)
+ {
+ auto token = ReadToken();
+ if (token.Content == expectedStr)
{
- if( NextToken().Type == tokenType )
- {
- ReadToken();
- return true;
- }
- throw TextFormatException("Text parsing error: unexpected '" + NextToken().Content + "'.");
+ return token.Content;
}
-
- String ReadStringLiteral()
+ throw TextFormatException("Text parsing error: \'" + expectedStr + "\' expected.");
+ }
+ bool Read(TokenType tokenType)
+ {
+ if (NextToken().Type == tokenType)
{
- auto token = ReadToken();
- if (token.Type == TokenType::StringLiteral)
- {
- return token.Content;
- }
- throw TextFormatException("Text parsing error: string literal expected.");
+ ReadToken();
+ return true;
}
- void Back(int count)
+ throw TextFormatException("Text parsing error: unexpected '" + NextToken().Content + "'.");
+ }
+
+ String ReadStringLiteral()
+ {
+ auto token = ReadToken();
+ if (token.Type == TokenType::StringLiteral)
{
- tokenPtr -= count;
+ return token.Content;
}
- Token ReadMatchingToken(TokenType type)
+ throw TextFormatException("Text parsing error: string literal expected.");
+ }
+ void Back(int count) { tokenPtr -= count; }
+ Token ReadMatchingToken(TokenType type)
+ {
+ auto token = ReadToken();
+ if (token.Type != type)
{
- auto token = ReadToken();
- if (token.Type != type)
- {
- throw TextFormatException("Text parsing error: unexpected token.");
- }
- return token;
+ throw TextFormatException("Text parsing error: unexpected token.");
}
- Token ReadToken()
+ return token;
+ }
+ Token ReadToken()
+ {
+ if (tokenPtr < (int)tokens.getCount())
{
- if (tokenPtr < (int)tokens.getCount())
- {
- auto &rs = tokens[tokenPtr];
- tokenPtr++;
- return rs;
- }
- throw TextFormatException("Unexpected ending.");
+ auto& rs = tokens[tokenPtr];
+ tokenPtr++;
+ return rs;
}
- Token NextToken(int offset = 0)
+ throw TextFormatException("Unexpected ending.");
+ }
+ Token NextToken(int offset = 0)
+ {
+ if (tokenPtr + offset < (int)tokens.getCount())
+ return tokens[tokenPtr + offset];
+ else
{
- if (tokenPtr + offset < (int)tokens.getCount())
- return tokens[tokenPtr + offset];
- else
- {
- Token rs;
- rs.Type = TokenType::Unknown;
- return rs;
- }
+ Token rs;
+ rs.Type = TokenType::Unknown;
+ return rs;
}
- bool LookAhead(String token)
+ }
+ bool LookAhead(String token)
+ {
+ if (tokenPtr < (int)tokens.getCount())
{
- if (tokenPtr < (int)tokens.getCount())
- {
- auto next = NextToken();
- return next.Content == token;
- }
- else
- {
- return false;
- }
+ auto next = NextToken();
+ return next.Content == token;
}
- bool LookAhead(TokenType tokenType)
+ else
{
- if (tokenPtr < (int)tokens.getCount())
- {
- auto next = NextToken();
- return next.Type == tokenType;
- }
- else
- {
- return false;
- }
+ return false;
}
- bool AdvanceIf(String token)
+ }
+ bool LookAhead(TokenType tokenType)
+ {
+ if (tokenPtr < (int)tokens.getCount())
{
- if( LookAhead(token) )
- {
- ReadToken();
- return true;
- }
- return false;
+ auto next = NextToken();
+ return next.Type == tokenType;
}
- bool AdvanceIf(TokenType token)
+ else
{
- if( LookAhead(token) )
- {
- ReadToken();
- return true;
- }
return false;
}
- bool IsEnd()
+ }
+ bool AdvanceIf(String token)
+ {
+ if (LookAhead(token))
{
- return tokenPtr == (int)tokens.getCount();
+ ReadToken();
+ return true;
}
- public:
- bool IsLegalText()
+ return false;
+ }
+ bool AdvanceIf(TokenType token)
+ {
+ if (LookAhead(token))
{
- return legal;
+ ReadToken();
+ return true;
}
- };
+ return false;
+ }
+ bool IsEnd() { return tokenPtr == (int)tokens.getCount(); }
+
+public:
+ bool IsLegalText() { return legal; }
+};
- inline List<String> Split(String text, char c)
+inline List<String> Split(String text, char c)
+{
+ List<String> result;
+ StringBuilder sb;
+ for (Index i = 0; i < text.getLength(); i++)
{
- List<String> result;
- StringBuilder sb;
- for (Index i = 0; i < text.getLength(); i++)
+ if (text[i] == c)
{
- if (text[i] == c)
- {
- auto str = sb.toString();
- if (str.getLength() != 0)
- result.add(str);
- sb.clear();
- }
- else
- sb << text[i];
+ auto str = sb.toString();
+ if (str.getLength() != 0)
+ result.add(str);
+ sb.clear();
}
- auto lastStr = sb.toString();
- if (lastStr.getLength())
- result.add(lastStr);
- return result;
+ else
+ sb << text[i];
}
+ auto lastStr = sb.toString();
+ if (lastStr.getLength())
+ result.add(lastStr);
+ return result;
+}
} // namespace Misc
} // namespace Slang
diff --git a/source/core/slang-type-convert-util.cpp b/source/core/slang-type-convert-util.cpp
index 12908f211..3eb053726 100644
--- a/source/core/slang-type-convert-util.cpp
+++ b/source/core/slang-type-convert-util.cpp
@@ -4,39 +4,40 @@
namespace Slang
{
-/* static */SlangSourceLanguage TypeConvertUtil::getSourceLanguageFromTarget(SlangCompileTarget target)
+/* static */ SlangSourceLanguage TypeConvertUtil::getSourceLanguageFromTarget(
+ SlangCompileTarget target)
{
switch (target)
{
- case SLANG_GLSL:
+ case SLANG_GLSL:
{
return SLANG_SOURCE_LANGUAGE_GLSL;
}
- case SLANG_HLSL: return SLANG_SOURCE_LANGUAGE_HLSL;
- case SLANG_C_SOURCE: return SLANG_SOURCE_LANGUAGE_C;
- case SLANG_CPP_SOURCE: return SLANG_SOURCE_LANGUAGE_CPP;
- case SLANG_CPP_PYTORCH_BINDING:return SLANG_SOURCE_LANGUAGE_CPP;
- case SLANG_HOST_CPP_SOURCE: return SLANG_SOURCE_LANGUAGE_CPP;
- case SLANG_CUDA_SOURCE: return SLANG_SOURCE_LANGUAGE_CUDA;
- case SLANG_WGSL: return SLANG_SOURCE_LANGUAGE_WGSL;
- default: break;
+ case SLANG_HLSL: return SLANG_SOURCE_LANGUAGE_HLSL;
+ case SLANG_C_SOURCE: return SLANG_SOURCE_LANGUAGE_C;
+ case SLANG_CPP_SOURCE: return SLANG_SOURCE_LANGUAGE_CPP;
+ case SLANG_CPP_PYTORCH_BINDING: return SLANG_SOURCE_LANGUAGE_CPP;
+ case SLANG_HOST_CPP_SOURCE: return SLANG_SOURCE_LANGUAGE_CPP;
+ case SLANG_CUDA_SOURCE: return SLANG_SOURCE_LANGUAGE_CUDA;
+ case SLANG_WGSL: return SLANG_SOURCE_LANGUAGE_WGSL;
+ default: break;
}
return SLANG_SOURCE_LANGUAGE_UNKNOWN;
}
-/* static */SlangCompileTarget TypeConvertUtil::getCompileTargetFromSourceLanguage(SlangSourceLanguage lang)
+/* static */ SlangCompileTarget TypeConvertUtil::getCompileTargetFromSourceLanguage(
+ SlangSourceLanguage lang)
{
switch (lang)
{
- case SLANG_SOURCE_LANGUAGE_GLSL: return SLANG_GLSL;
- case SLANG_SOURCE_LANGUAGE_HLSL: return SLANG_HLSL;
- case SLANG_SOURCE_LANGUAGE_C: return SLANG_C_SOURCE;
- case SLANG_SOURCE_LANGUAGE_CPP: return SLANG_CPP_SOURCE;
- case SLANG_SOURCE_LANGUAGE_CUDA: return SLANG_CUDA_SOURCE;
+ case SLANG_SOURCE_LANGUAGE_GLSL: return SLANG_GLSL;
+ case SLANG_SOURCE_LANGUAGE_HLSL: return SLANG_HLSL;
+ case SLANG_SOURCE_LANGUAGE_C: return SLANG_C_SOURCE;
+ case SLANG_SOURCE_LANGUAGE_CPP: return SLANG_CPP_SOURCE;
+ case SLANG_SOURCE_LANGUAGE_CUDA: return SLANG_CUDA_SOURCE;
}
return SLANG_TARGET_UNKNOWN;
}
-}
-
+} // namespace Slang
diff --git a/source/core/slang-type-convert-util.h b/source/core/slang-type-convert-util.h
index 70565b896..d4c80abf8 100644
--- a/source/core/slang-type-convert-util.h
+++ b/source/core/slang-type-convert-util.h
@@ -9,13 +9,14 @@ namespace Slang
/// Utility class for simple conversions between types
struct TypeConvertUtil
{
- /// Convert a target into it's equivalent language if ones available. If not returns SOURCE_LANGUAGE_UNKNOWN
+ /// Convert a target into it's equivalent language if ones available. If not returns
+ /// SOURCE_LANGUAGE_UNKNOWN
static SlangSourceLanguage getSourceLanguageFromTarget(SlangCompileTarget target);
- /// Convert a language into the equivalent target. If not available returns SLANG_TARGET_UNKNOWN
+ /// Convert a language into the equivalent target. If not available returns SLANG_TARGET_UNKNOWN
static SlangCompileTarget getCompileTargetFromSourceLanguage(SlangSourceLanguage lang);
};
-}
+} // namespace Slang
#endif // SLANG_CORE_TYPE_TEXT_UTIL_H
diff --git a/source/core/slang-type-text-util.cpp b/source/core/slang-type-text-util.cpp
index 51ed2060e..0afd25342 100644
--- a/source/core/slang-type-text-util.cpp
+++ b/source/core/slang-type-text-util.cpp
@@ -1,13 +1,14 @@
#include "slang-type-text-util.h"
-#include "slang-array-view.h"
+#include "slang-array-view.h"
#include "slang-string-util.h"
namespace Slang
{
-namespace { // anonymous
+namespace
+{ // anonymous
// clang-format off
#define SLANG_SCALAR_TYPES(x) \
@@ -20,7 +21,7 @@ namespace { // anonymous
x(Int64, int64_t) \
x(UInt64, uint64_t) \
x(Float32, float) \
- x(Float64, double)
+ x(Float64, double)
// clang-format on
struct ScalarTypeInfo
@@ -29,198 +30,235 @@ struct ScalarTypeInfo
UnownedStringSlice text;
};
-static const ScalarTypeInfo s_scalarTypeInfos[] =
-{
- #define SLANG_SCALAR_TYPE_INFO(value, text) \
- { slang::TypeReflection::ScalarType::value, UnownedStringSlice::fromLiteral(#text) },
- SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO)
-};
+static const ScalarTypeInfo s_scalarTypeInfos[] = {
+#define SLANG_SCALAR_TYPE_INFO(value, text) \
+ {slang::TypeReflection::ScalarType::value, UnownedStringSlice::fromLiteral(#text)},
+ SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO)};
// Make sure to keep this table in sync with that in slang/slang-options.cpp getHelpText
-static const TypeTextUtil::CompileTargetInfo s_compileTargetInfos[] =
-{
- { SLANG_TARGET_UNKNOWN, "", "unknown"},
- { SLANG_TARGET_NONE, "", "none"},
- { SLANG_HLSL, "hlsl,fx", "hlsl", "HLSL source code"},
- { SLANG_DXBC, "dxbc", "dxbc", "DirectX shader bytecode binary"},
- { SLANG_DXBC_ASM, "dxbc-asm", "dxbc-asm,dxbc-assembly", "DirectX shader bytecode assembly" },
- { SLANG_DXIL, "dxil", "dxil", "DirectX Intermediate Language binary" },
- { SLANG_DXIL_ASM, "dxil-asm", "dxil-asm,dxil-assembly", "DirectX Intermediate Language assembly"},
- { SLANG_GLSL, "glsl,vert,frag,geom,tesc,tese,comp", "glsl", "GLSL(Vulkan) source code" },
- { SLANG_SPIRV, "spv", "spirv", "SPIR-V binary"},
- { SLANG_SPIRV_ASM, "spv-asm", "spirv-asm,spirv-assembly", "SPIR-V assembly" },
- { SLANG_C_SOURCE, "c", "c", "C source code" },
- { SLANG_CPP_SOURCE, "cpp,c++,cxx", "cpp,c++,cxx", "C++ source code" },
- { SLANG_CPP_PYTORCH_BINDING, "cpp,c++,cxx", "torch,torch-binding,torch-cpp,torch-cpp-binding", "C++ for pytorch binding" },
- { SLANG_HOST_CPP_SOURCE, "cpp,c++,cxx", "host-cpp,host-c++,host-cxx", "C++ source for host execution"},
- { SLANG_HOST_EXECUTABLE,"exe", "exe,executable", "Executable binary" },
- { SLANG_SHADER_SHARED_LIBRARY, "shader-dll,shader-so", "shader-sharedlib,shader-sharedlibrary,shader-dll", "Shared library/Dll for shader kernel" },
- { SLANG_HOST_SHARED_LIBRARY, "dll,so", "sharedlib,sharedlibrary,dll", "Shared library/Dll for host execution" },
- { SLANG_CUDA_SOURCE, "cu", "cuda,cu", "CUDA source code" },
- { SLANG_PTX, "ptx", "ptx", "PTX assembly" },
- { SLANG_CUDA_OBJECT_CODE, "obj,o", "cuobj,cubin", "CUDA binary" },
- { SLANG_SHADER_HOST_CALLABLE, "", "host-callable,callable", "Host callable" },
- { SLANG_OBJECT_CODE, "obj,o", "object-code", "Object code" },
- { SLANG_HOST_HOST_CALLABLE, "", "host-host-callable", "Host callable for host execution" },
- { SLANG_METAL, "metal", "metal", "Metal shader source" },
- { SLANG_METAL_LIB, "metallib", "metallib", "Metal Library Bytecode" },
- { SLANG_METAL_LIB_ASM, "metallib-asm" "metallib-asm", "Metal Library Bytecode assembly" },
- { SLANG_WGSL, "wgsl", "wgsl", "WebGPU shading language source" },
- { SLANG_WGSL_SPIRV_ASM, "wgsl-spirv-asm", "wgsl-spirv-asm,wgsl-spirv-assembly", "SPIR-V assembly via WebGPU shading language" },
- { SLANG_WGSL_SPIRV, "wgsl-spirv", "wgsl-spirv", "SPIR-V via WebGPU shading language" },
+static const TypeTextUtil::CompileTargetInfo s_compileTargetInfos[] = {
+ {SLANG_TARGET_UNKNOWN, "", "unknown"},
+ {SLANG_TARGET_NONE, "", "none"},
+ {SLANG_HLSL, "hlsl,fx", "hlsl", "HLSL source code"},
+ {SLANG_DXBC, "dxbc", "dxbc", "DirectX shader bytecode binary"},
+ {SLANG_DXBC_ASM, "dxbc-asm", "dxbc-asm,dxbc-assembly", "DirectX shader bytecode assembly"},
+ {SLANG_DXIL, "dxil", "dxil", "DirectX Intermediate Language binary"},
+ {SLANG_DXIL_ASM,
+ "dxil-asm",
+ "dxil-asm,dxil-assembly",
+ "DirectX Intermediate Language assembly"},
+ {SLANG_GLSL, "glsl,vert,frag,geom,tesc,tese,comp", "glsl", "GLSL(Vulkan) source code"},
+ {SLANG_SPIRV, "spv", "spirv", "SPIR-V binary"},
+ {SLANG_SPIRV_ASM, "spv-asm", "spirv-asm,spirv-assembly", "SPIR-V assembly"},
+ {SLANG_C_SOURCE, "c", "c", "C source code"},
+ {SLANG_CPP_SOURCE, "cpp,c++,cxx", "cpp,c++,cxx", "C++ source code"},
+ {SLANG_CPP_PYTORCH_BINDING,
+ "cpp,c++,cxx",
+ "torch,torch-binding,torch-cpp,torch-cpp-binding",
+ "C++ for pytorch binding"},
+ {SLANG_HOST_CPP_SOURCE,
+ "cpp,c++,cxx",
+ "host-cpp,host-c++,host-cxx",
+ "C++ source for host execution"},
+ {SLANG_HOST_EXECUTABLE, "exe", "exe,executable", "Executable binary"},
+ {SLANG_SHADER_SHARED_LIBRARY,
+ "shader-dll,shader-so",
+ "shader-sharedlib,shader-sharedlibrary,shader-dll",
+ "Shared library/Dll for shader kernel"},
+ {SLANG_HOST_SHARED_LIBRARY,
+ "dll,so",
+ "sharedlib,sharedlibrary,dll",
+ "Shared library/Dll for host execution"},
+ {SLANG_CUDA_SOURCE, "cu", "cuda,cu", "CUDA source code"},
+ {SLANG_PTX, "ptx", "ptx", "PTX assembly"},
+ {SLANG_CUDA_OBJECT_CODE, "obj,o", "cuobj,cubin", "CUDA binary"},
+ {SLANG_SHADER_HOST_CALLABLE, "", "host-callable,callable", "Host callable"},
+ {SLANG_OBJECT_CODE, "obj,o", "object-code", "Object code"},
+ {SLANG_HOST_HOST_CALLABLE, "", "host-host-callable", "Host callable for host execution"},
+ {SLANG_METAL, "metal", "metal", "Metal shader source"},
+ {SLANG_METAL_LIB, "metallib", "metallib", "Metal Library Bytecode"},
+ {SLANG_METAL_LIB_ASM,
+ "metallib-asm"
+ "metallib-asm",
+ "Metal Library Bytecode assembly"},
+ {SLANG_WGSL, "wgsl", "wgsl", "WebGPU shading language source"},
+ {SLANG_WGSL_SPIRV_ASM,
+ "wgsl-spirv-asm",
+ "wgsl-spirv-asm,wgsl-spirv-assembly",
+ "SPIR-V assembly via WebGPU shading language"},
+ {SLANG_WGSL_SPIRV, "wgsl-spirv", "wgsl-spirv", "SPIR-V via WebGPU shading language"},
};
-static const NamesDescriptionValue s_languageInfos[] =
-{
- { SLANG_SOURCE_LANGUAGE_C, "c,C", "C language" },
- { SLANG_SOURCE_LANGUAGE_CPP, "cpp,c++,C++,cxx", "C++ language" },
- { SLANG_SOURCE_LANGUAGE_SLANG, "slang", "Slang language" },
- { SLANG_SOURCE_LANGUAGE_GLSL, "glsl", "GLSL language" },
- { SLANG_SOURCE_LANGUAGE_HLSL, "hlsl", "HLSL language" },
- { SLANG_SOURCE_LANGUAGE_CUDA, "cu,cuda", "CUDA" },
-};
-
-static const NamesDescriptionValue s_compilerInfos[] =
-{
- { SLANG_PASS_THROUGH_NONE, "none", "Unknown" },
- { SLANG_PASS_THROUGH_FXC, "fxc", "FXC HLSL compiler" },
- { SLANG_PASS_THROUGH_DXC, "dxc", "DXC HLSL compiler" },
- { SLANG_PASS_THROUGH_GLSLANG, "glslang", "GLSLANG GLSL compiler" },
- { SLANG_PASS_THROUGH_SPIRV_DIS, "spirv-dis", "spirv-tools SPIRV disassembler" },
- { SLANG_PASS_THROUGH_CLANG, "clang", "Clang C/C++ compiler" },
- { SLANG_PASS_THROUGH_VISUAL_STUDIO, "visualstudio,vs", "Visual Studio C/C++ compiler" },
- { SLANG_PASS_THROUGH_GCC, "gcc", "GCC C/C++ compiler" },
- { SLANG_PASS_THROUGH_GENERIC_C_CPP, "genericcpp,c,cpp", "A generic C++ compiler (can be any one of visual studio, clang or gcc depending on system and availability)" },
- { SLANG_PASS_THROUGH_NVRTC, "nvrtc", "NVRTC CUDA compiler" },
- { SLANG_PASS_THROUGH_LLVM, "llvm", "LLVM/Clang `slang-llvm`" },
- { SLANG_PASS_THROUGH_SPIRV_OPT, "spirv-opt", "spirv-tools SPIRV optimizer" },
- { SLANG_PASS_THROUGH_METAL, "metal", "Metal shader compiler" },
- { SLANG_PASS_THROUGH_TINT, "tint", "Tint compiler" },
+static const NamesDescriptionValue s_languageInfos[] = {
+ {SLANG_SOURCE_LANGUAGE_C, "c,C", "C language"},
+ {SLANG_SOURCE_LANGUAGE_CPP, "cpp,c++,C++,cxx", "C++ language"},
+ {SLANG_SOURCE_LANGUAGE_SLANG, "slang", "Slang language"},
+ {SLANG_SOURCE_LANGUAGE_GLSL, "glsl", "GLSL language"},
+ {SLANG_SOURCE_LANGUAGE_HLSL, "hlsl", "HLSL language"},
+ {SLANG_SOURCE_LANGUAGE_CUDA, "cu,cuda", "CUDA"},
};
-static const NamesDescriptionValue s_archiveTypeInfos[] =
-{
- { SLANG_ARCHIVE_TYPE_RIFF_DEFLATE, "riff-deflate", "Slang RIFF using deflate compression" },
- { SLANG_ARCHIVE_TYPE_RIFF_LZ4, "riff-lz4", "Slang RIFF using LZ4 compression" },
- { SLANG_ARCHIVE_TYPE_ZIP, "zip", "Zip file" },
- { SLANG_ARCHIVE_TYPE_RIFF, "riff", "Slang RIFF without compression" },
+static const NamesDescriptionValue s_compilerInfos[] = {
+ {SLANG_PASS_THROUGH_NONE, "none", "Unknown"},
+ {SLANG_PASS_THROUGH_FXC, "fxc", "FXC HLSL compiler"},
+ {SLANG_PASS_THROUGH_DXC, "dxc", "DXC HLSL compiler"},
+ {SLANG_PASS_THROUGH_GLSLANG, "glslang", "GLSLANG GLSL compiler"},
+ {SLANG_PASS_THROUGH_SPIRV_DIS, "spirv-dis", "spirv-tools SPIRV disassembler"},
+ {SLANG_PASS_THROUGH_CLANG, "clang", "Clang C/C++ compiler"},
+ {SLANG_PASS_THROUGH_VISUAL_STUDIO, "visualstudio,vs", "Visual Studio C/C++ compiler"},
+ {SLANG_PASS_THROUGH_GCC, "gcc", "GCC C/C++ compiler"},
+ {SLANG_PASS_THROUGH_GENERIC_C_CPP,
+ "genericcpp,c,cpp",
+ "A generic C++ compiler (can be any one of visual studio, clang or gcc depending on system "
+ "and availability)"},
+ {SLANG_PASS_THROUGH_NVRTC, "nvrtc", "NVRTC CUDA compiler"},
+ {SLANG_PASS_THROUGH_LLVM, "llvm", "LLVM/Clang `slang-llvm`"},
+ {SLANG_PASS_THROUGH_SPIRV_OPT, "spirv-opt", "spirv-tools SPIRV optimizer"},
+ {SLANG_PASS_THROUGH_METAL, "metal", "Metal shader compiler"},
+ {SLANG_PASS_THROUGH_TINT, "tint", "Tint compiler"},
};
-static const NamesDescriptionValue s_debugInfoFormatInfos[] =
-{
- { SLANG_DEBUG_INFO_FORMAT_DEFAULT, "default-format", "Use the default debugging format for the target" },
- { SLANG_DEBUG_INFO_FORMAT_C7, "c7", "CodeView C7 format (typically means debugging infomation is embedded in the binary)" },
- { SLANG_DEBUG_INFO_FORMAT_PDB, "pdb", "Program database" },
- { SLANG_DEBUG_INFO_FORMAT_STABS, "stabs", "STABS debug format" },
- { SLANG_DEBUG_INFO_FORMAT_COFF, "coff", "COFF debug format" },
- { SLANG_DEBUG_INFO_FORMAT_DWARF, "dwarf", "DWARF debug format"},
+static const NamesDescriptionValue s_archiveTypeInfos[] = {
+ {SLANG_ARCHIVE_TYPE_RIFF_DEFLATE, "riff-deflate", "Slang RIFF using deflate compression"},
+ {SLANG_ARCHIVE_TYPE_RIFF_LZ4, "riff-lz4", "Slang RIFF using LZ4 compression"},
+ {SLANG_ARCHIVE_TYPE_ZIP, "zip", "Zip file"},
+ {SLANG_ARCHIVE_TYPE_RIFF, "riff", "Slang RIFF without compression"},
};
-static const NamesDescriptionValue s_lineDirectiveInfos[] =
-{
- { SLANG_LINE_DIRECTIVE_MODE_NONE, "none", "Don't emit `#line` directives at all"},
- { SLANG_LINE_DIRECTIVE_MODE_SOURCE_MAP, "source-map", "Use source map to track line associations (doen't emit #line)"},
- { SLANG_LINE_DIRECTIVE_MODE_DEFAULT, "default", "Default behavior"},
- { SLANG_LINE_DIRECTIVE_MODE_STANDARD, "standard", "Emit standard C-style `#line` directives." },
- { SLANG_LINE_DIRECTIVE_MODE_GLSL, "glsl", "Emit GLSL-style directives with file *number* instead of name." },
+static const NamesDescriptionValue s_debugInfoFormatInfos[] = {
+ {SLANG_DEBUG_INFO_FORMAT_DEFAULT,
+ "default-format",
+ "Use the default debugging format for the target"},
+ {SLANG_DEBUG_INFO_FORMAT_C7,
+ "c7",
+ "CodeView C7 format (typically means debugging infomation is embedded in the binary)"},
+ {SLANG_DEBUG_INFO_FORMAT_PDB, "pdb", "Program database"},
+ {SLANG_DEBUG_INFO_FORMAT_STABS, "stabs", "STABS debug format"},
+ {SLANG_DEBUG_INFO_FORMAT_COFF, "coff", "COFF debug format"},
+ {SLANG_DEBUG_INFO_FORMAT_DWARF, "dwarf", "DWARF debug format"},
};
-static const NamesDescriptionValue s_floatingPointModes[] =
-{
- { SLANG_FLOATING_POINT_MODE_PRECISE, "precise",
- "Disable optimization that could change the output of floating-"
- "point computations, including around infinities, NaNs, denormalized "
- "values, and negative zero. Prefer the most precise versions of special "
- "functions supported by the target."},
- { SLANG_FLOATING_POINT_MODE_FAST,"fast",
- "Allow optimizations that may change results of floating-point "
- "computations. Prefer the fastest version of special functions supported "
- "by the target."},
- { SLANG_FLOATING_POINT_MODE_DEFAULT, "default",
- "Default floating point mode" }
+static const NamesDescriptionValue s_lineDirectiveInfos[] = {
+ {SLANG_LINE_DIRECTIVE_MODE_NONE, "none", "Don't emit `#line` directives at all"},
+ {SLANG_LINE_DIRECTIVE_MODE_SOURCE_MAP,
+ "source-map",
+ "Use source map to track line associations (doen't emit #line)"},
+ {SLANG_LINE_DIRECTIVE_MODE_DEFAULT, "default", "Default behavior"},
+ {SLANG_LINE_DIRECTIVE_MODE_STANDARD, "standard", "Emit standard C-style `#line` directives."},
+ {SLANG_LINE_DIRECTIVE_MODE_GLSL,
+ "glsl",
+ "Emit GLSL-style directives with file *number* instead of name."},
};
-static const NamesDescriptionValue s_optimizationLevels[] =
-{
- { SLANG_OPTIMIZATION_LEVEL_NONE, "0,none", "Disable all optimizations" },
- { SLANG_OPTIMIZATION_LEVEL_DEFAULT, "1,default", "Enable a default level of optimization.This is the default if no -o options are used." },
- { SLANG_OPTIMIZATION_LEVEL_HIGH, "2,high", "Enable aggressive optimizations for speed." },
- { SLANG_OPTIMIZATION_LEVEL_MAXIMAL, "3,maximal", "Enable further optimizations, which might have a significant impact on compile time, or involve unwanted tradeoffs in terms of code size." },
+static const NamesDescriptionValue s_floatingPointModes[] = {
+ {SLANG_FLOATING_POINT_MODE_PRECISE,
+ "precise",
+ "Disable optimization that could change the output of floating-"
+ "point computations, including around infinities, NaNs, denormalized "
+ "values, and negative zero. Prefer the most precise versions of special "
+ "functions supported by the target."},
+ {SLANG_FLOATING_POINT_MODE_FAST,
+ "fast",
+ "Allow optimizations that may change results of floating-point "
+ "computations. Prefer the fastest version of special functions supported "
+ "by the target."},
+ {SLANG_FLOATING_POINT_MODE_DEFAULT, "default", "Default floating point mode"}};
+
+static const NamesDescriptionValue s_optimizationLevels[] = {
+ {SLANG_OPTIMIZATION_LEVEL_NONE, "0,none", "Disable all optimizations"},
+ {SLANG_OPTIMIZATION_LEVEL_DEFAULT,
+ "1,default",
+ "Enable a default level of optimization.This is the default if no -o options are used."},
+ {SLANG_OPTIMIZATION_LEVEL_HIGH, "2,high", "Enable aggressive optimizations for speed."},
+ {SLANG_OPTIMIZATION_LEVEL_MAXIMAL,
+ "3,maximal",
+ "Enable further optimizations, which might have a significant impact on compile time, or "
+ "involve unwanted tradeoffs in terms of code size."},
};
-static const NamesDescriptionValue s_debugLevels[] =
-{
- { SLANG_DEBUG_INFO_LEVEL_NONE, "0,none", "Don't emit debug information at all." },
- { SLANG_DEBUG_INFO_LEVEL_MINIMAL, "1,minimal", "Emit as little debug information as possible, while still supporting stack traces." },
- { SLANG_DEBUG_INFO_LEVEL_STANDARD, "2,standard", "Emit whatever is the standard level of debug information for each target." },
- { SLANG_DEBUG_INFO_LEVEL_MAXIMAL, "3,maximal", "Emit as much debug information as possible for each target." },
+static const NamesDescriptionValue s_debugLevels[] = {
+ {SLANG_DEBUG_INFO_LEVEL_NONE, "0,none", "Don't emit debug information at all."},
+ {SLANG_DEBUG_INFO_LEVEL_MINIMAL,
+ "1,minimal",
+ "Emit as little debug information as possible, while still supporting stack traces."},
+ {SLANG_DEBUG_INFO_LEVEL_STANDARD,
+ "2,standard",
+ "Emit whatever is the standard level of debug information for each target."},
+ {SLANG_DEBUG_INFO_LEVEL_MAXIMAL,
+ "3,maximal",
+ "Emit as much debug information as possible for each target."},
};
-static const NamesDescriptionValue s_fileSystemTypes[] =
-{
- { ValueInt(TypeTextUtil::FileSystemType::Default), "default", "Default file system." },
- { ValueInt(TypeTextUtil::FileSystemType::LoadFile), "load-file", "Just implements loadFile interface, so will be wrapped with CacheFileSystem internally." },
- { ValueInt(TypeTextUtil::FileSystemType::Os), "os", "Use the OS based file system directly (without file system caching)" },
+static const NamesDescriptionValue s_fileSystemTypes[] = {
+ {ValueInt(TypeTextUtil::FileSystemType::Default), "default", "Default file system."},
+ {ValueInt(TypeTextUtil::FileSystemType::LoadFile),
+ "load-file",
+ "Just implements loadFile interface, so will be wrapped with CacheFileSystem internally."},
+ {ValueInt(TypeTextUtil::FileSystemType::Os),
+ "os",
+ "Use the OS based file system directly (without file system caching)"},
};
-} // anonymous
+} // namespace
-/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getFileSystemTypeInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getFileSystemTypeInfos()
{
return makeConstArrayView(s_fileSystemTypes);
}
-/* static */ConstArrayView<TypeTextUtil::CompileTargetInfo> TypeTextUtil::getCompileTargetInfos()
+/* static */ ConstArrayView<TypeTextUtil::CompileTargetInfo> TypeTextUtil::getCompileTargetInfos()
{
return makeConstArrayView(s_compileTargetInfos);
}
-/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getLanguageInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getLanguageInfos()
{
return makeConstArrayView(s_languageInfos);
}
-/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getCompilerInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getCompilerInfos()
{
return makeConstArrayView(s_compilerInfos);
}
-/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getArchiveTypeInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getArchiveTypeInfos()
{
return makeConstArrayView(s_archiveTypeInfos);
}
-/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getDebugInfoFormatInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getDebugInfoFormatInfos()
{
return makeConstArrayView(s_debugInfoFormatInfos);
}
-/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getLineDirectiveInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getLineDirectiveInfos()
{
return makeConstArrayView(s_lineDirectiveInfos);
}
-/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getFloatingPointModeInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getFloatingPointModeInfos()
{
return makeConstArrayView(s_floatingPointModes);
}
-/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getOptimizationLevelInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getOptimizationLevelInfos()
{
return makeConstArrayView(s_optimizationLevels);
}
-/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getDebugLevelInfos()
+/* static */ ConstArrayView<NamesDescriptionValue> TypeTextUtil::getDebugLevelInfos()
{
return makeConstArrayView(s_debugLevels);
}
-/* static */SlangArchiveType TypeTextUtil::findArchiveType(const UnownedStringSlice& slice)
+/* static */ SlangArchiveType TypeTextUtil::findArchiveType(const UnownedStringSlice& slice)
{
return NameValueUtil::findValue(getArchiveTypeInfos(), slice, SLANG_ARCHIVE_TYPE_UNDEFINED);
}
-/* static */SlangResult TypeTextUtil::findDebugInfoFormat(const Slang::UnownedStringSlice& text, SlangDebugInfoFormat& out)
+/* static */ SlangResult TypeTextUtil::findDebugInfoFormat(
+ const Slang::UnownedStringSlice& text,
+ SlangDebugInfoFormat& out)
{
const ValueInt value = NameValueUtil::findValue(getDebugInfoFormatInfos(), text, -1);
if (value >= 0)
@@ -231,25 +269,28 @@ static const NamesDescriptionValue s_fileSystemTypes[] =
return SLANG_FAIL;
}
-/* static */UnownedStringSlice TypeTextUtil::getDebugInfoFormatName(SlangDebugInfoFormat format)
+/* static */ UnownedStringSlice TypeTextUtil::getDebugInfoFormatName(SlangDebugInfoFormat format)
{
return NameValueUtil::findName(getDebugInfoFormatInfos(), format, toSlice("unknown"));
}
-/* static */UnownedStringSlice TypeTextUtil::getScalarTypeName(slang::TypeReflection::ScalarType scalarType)
-{
+/* static */ UnownedStringSlice TypeTextUtil::getScalarTypeName(
+ slang::TypeReflection::ScalarType scalarType)
+{
typedef slang::TypeReflection::ScalarType ScalarType;
switch (scalarType)
{
-#define SLANG_SCALAR_TYPE_TO_TEXT(value, text) case ScalarType::value: return UnownedStringSlice::fromLiteral(#text);
+#define SLANG_SCALAR_TYPE_TO_TEXT(value, text) \
+ case ScalarType::value: return UnownedStringSlice::fromLiteral(#text);
SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_TO_TEXT)
- default: break;
+ default: break;
}
return UnownedStringSlice();
}
-/* static */slang::TypeReflection::ScalarType TypeTextUtil::findScalarType(const UnownedStringSlice& inText)
+/* static */ slang::TypeReflection::ScalarType TypeTextUtil::findScalarType(
+ const UnownedStringSlice& inText)
{
for (Index i = 0; i < SLANG_COUNT_OF(s_scalarTypeInfos); ++i)
{
@@ -263,38 +304,42 @@ static const NamesDescriptionValue s_fileSystemTypes[] =
}
-/* static */UnownedStringSlice TypeTextUtil::getPassThroughAsHumanText(SlangPassThrough type)
+/* static */ UnownedStringSlice TypeTextUtil::getPassThroughAsHumanText(SlangPassThrough type)
{
return NameValueUtil::findName(getCompilerInfos(), type, toSlice("unknown"));
}
-/* static */SlangSourceLanguage TypeTextUtil::findSourceLanguage(const UnownedStringSlice& text)
+/* static */ SlangSourceLanguage TypeTextUtil::findSourceLanguage(const UnownedStringSlice& text)
{
return NameValueUtil::findValue(getLanguageInfos(), text, SLANG_SOURCE_LANGUAGE_UNKNOWN);
}
-/* static */SlangPassThrough TypeTextUtil::findPassThrough(const UnownedStringSlice& slice)
+/* static */ SlangPassThrough TypeTextUtil::findPassThrough(const UnownedStringSlice& slice)
{
return NameValueUtil::findValue(getCompilerInfos(), slice, SLANG_PASS_THROUGH_NONE);
}
-/* static */SlangResult TypeTextUtil::findPassThrough(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough)
+/* static */ SlangResult TypeTextUtil::findPassThrough(
+ const UnownedStringSlice& slice,
+ SlangPassThrough& outPassThrough)
{
outPassThrough = findPassThrough(slice);
// It could be none on error - if it's not equal to "none" then it must be an error
- if (outPassThrough == SLANG_PASS_THROUGH_NONE && slice != UnownedStringSlice::fromLiteral("none"))
+ if (outPassThrough == SLANG_PASS_THROUGH_NONE &&
+ slice != UnownedStringSlice::fromLiteral("none"))
{
return SLANG_FAIL;
}
return SLANG_OK;
}
-/* static */UnownedStringSlice TypeTextUtil::getPassThroughName(SlangPassThrough passThru)
+/* static */ UnownedStringSlice TypeTextUtil::getPassThroughName(SlangPassThrough passThru)
{
return NameValueUtil::findName(getCompilerInfos(), passThru, toSlice("unknown"));
}
-/* static */SlangCompileTarget TypeTextUtil::findCompileTargetFromExtension(const UnownedStringSlice& slice)
+/* static */ SlangCompileTarget TypeTextUtil::findCompileTargetFromExtension(
+ const UnownedStringSlice& slice)
{
if (slice.getLength())
{
@@ -309,7 +354,8 @@ static const NamesDescriptionValue s_fileSystemTypes[] =
return SLANG_TARGET_UNKNOWN;
}
-/* static */ SlangCompileTarget TypeTextUtil::findCompileTargetFromName(const UnownedStringSlice& slice)
+/* static */ SlangCompileTarget TypeTextUtil::findCompileTargetFromName(
+ const UnownedStringSlice& slice)
{
if (slice.getLength())
{
@@ -340,8 +386,11 @@ UnownedStringSlice TypeTextUtil::getCompileTargetName(SlangCompileTarget target)
{
const Index index = _getTargetInfoIndex(target);
// Return the first name
- return index >= 0 ? StringUtil::getAtInSplit(UnownedStringSlice(s_compileTargetInfos[index].names), ',', 0) : UnownedStringSlice();
-}
-
+ return index >= 0 ? StringUtil::getAtInSplit(
+ UnownedStringSlice(s_compileTargetInfos[index].names),
+ ',',
+ 0)
+ : UnownedStringSlice();
}
+} // namespace Slang
diff --git a/source/core/slang-type-text-util.h b/source/core/slang-type-text-util.h
index 6d07e7d58..730888254 100644
--- a/source/core/slang-type-text-util.h
+++ b/source/core/slang-type-text-util.h
@@ -1,11 +1,10 @@
#ifndef SLANG_CORE_TYPE_TEXT_UTIL_H
#define SLANG_CORE_TYPE_TEXT_UTIL_H
-#include "slang.h"
-
-#include "slang-string.h"
#include "slang-array-view.h"
#include "slang-name-value.h"
+#include "slang-string.h"
+#include "slang.h"
namespace Slang
{
@@ -22,74 +21,80 @@ struct TypeTextUtil
struct CompileTargetInfo
{
- SlangCompileTarget target; ///< The target
- const char* extensions; ///< Comma delimited list of extensions associated with the target
- const char* names; ///< Comma delimited list of names associated with the target. NOTE! First name is taken as the normal display name.
- const char* description = nullptr; ///< Description, can be null
+ SlangCompileTarget target; ///< The target
+ const char* extensions; ///< Comma delimited list of extensions associated with the target
+ const char* names; ///< Comma delimited list of names associated with the target. NOTE!
+ ///< First name is taken as the normal display name.
+ const char* description = nullptr; ///< Description, can be null
};
-
- /// Get the compile target infos
+
+ /// Get the compile target infos
static ConstArrayView<CompileTargetInfo> getCompileTargetInfos();
- /// Get the language infos
+ /// Get the language infos
static ConstArrayView<NamesDescriptionValue> getLanguageInfos();
- /// Get the compiler infos
+ /// Get the compiler infos
static ConstArrayView<NamesDescriptionValue> getCompilerInfos();
- /// Get the archive type infos
+ /// Get the archive type infos
static ConstArrayView<NamesDescriptionValue> getArchiveTypeInfos();
- /// Get the debug format types
+ /// Get the debug format types
static ConstArrayView<NamesDescriptionValue> getDebugInfoFormatInfos();
- /// Get the debug levels
+ /// Get the debug levels
static ConstArrayView<NamesDescriptionValue> getDebugLevelInfos();
- /// Get the floating point modes
+ /// Get the floating point modes
static ConstArrayView<NamesDescriptionValue> getFloatingPointModeInfos();
- // Get the line directive infos
+ // Get the line directive infos
static ConstArrayView<NamesDescriptionValue> getLineDirectiveInfos();
- /// Get the optimization level info
+ /// Get the optimization level info
static ConstArrayView<NamesDescriptionValue> getOptimizationLevelInfos();
- /// Get the file system type infos
+ /// Get the file system type infos
static ConstArrayView<NamesDescriptionValue> getFileSystemTypeInfos();
- /// Get the scalar type as text.
- static Slang::UnownedStringSlice getScalarTypeName(slang::TypeReflection::ScalarType scalarType);
+ /// Get the scalar type as text.
+ static Slang::UnownedStringSlice getScalarTypeName(
+ slang::TypeReflection::ScalarType scalarType);
- // Converts text to scalar type. Returns 'none' if not determined
+ // Converts text to scalar type. Returns 'none' if not determined
static slang::TypeReflection::ScalarType findScalarType(const Slang::UnownedStringSlice& text);
- /// Given a slice finds the associated debug info format
- static SlangResult findDebugInfoFormat(const Slang::UnownedStringSlice& text, SlangDebugInfoFormat& out);
+ /// Given a slice finds the associated debug info format
+ static SlangResult findDebugInfoFormat(
+ const Slang::UnownedStringSlice& text,
+ SlangDebugInfoFormat& out);
- /// Get the text name for a format
+ /// Get the text name for a format
static UnownedStringSlice getDebugInfoFormatName(SlangDebugInfoFormat format);
- /// As human readable text
+ /// As human readable text
static UnownedStringSlice getPassThroughAsHumanText(SlangPassThrough type);
-
- /// Given a source language name returns a source language. Name here is distinct from extension
+
+ /// Given a source language name returns a source language. Name here is distinct from extension
static SlangSourceLanguage findSourceLanguage(const UnownedStringSlice& text);
- /// Given a name returns the pass through
+ /// Given a name returns the pass through
static SlangPassThrough findPassThrough(const UnownedStringSlice& slice);
- static SlangResult findPassThrough(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough);
+ static SlangResult findPassThrough(
+ const UnownedStringSlice& slice,
+ SlangPassThrough& outPassThrough);
- /// Get the compilers name
+ /// Get the compilers name
static UnownedStringSlice getPassThroughName(SlangPassThrough passThru);
- /// Given a file extension determines suitable target
- /// If doesn't match any target will return SLANG_TARGET_UNKNOWN
+ /// Given a file extension determines suitable target
+ /// If doesn't match any target will return SLANG_TARGET_UNKNOWN
static SlangCompileTarget findCompileTargetFromExtension(const UnownedStringSlice& slice);
- /// Given a name suitable target
- /// If doesn't match any target will return SLANG_TARGET_UNKNOWN
+ /// Given a name suitable target
+ /// If doesn't match any target will return SLANG_TARGET_UNKNOWN
static SlangCompileTarget findCompileTargetFromName(const UnownedStringSlice& slice);
- /// Given a target returns the associated name.
+ /// Given a target returns the associated name.
static UnownedStringSlice getCompileTargetName(SlangCompileTarget target);
- /// Returns SLANG_ARCHIVE_TYPE_UNKNOWN if a match is not found
+ /// Returns SLANG_ARCHIVE_TYPE_UNKNOWN if a match is not found
static SlangArchiveType findArchiveType(const UnownedStringSlice& slice);
};
-}
+} // namespace Slang
#endif // SLANG_CORE_TYPE_TEXT_UTIL_H
diff --git a/source/core/slang-type-traits.h b/source/core/slang-type-traits.h
index ccd1fb29c..193dc948f 100644
--- a/source/core/slang-type-traits.h
+++ b/source/core/slang-type-traits.h
@@ -3,44 +3,58 @@
namespace Slang
{
- struct TraitResultYes
- {
- char x;
- };
- struct TraitResultNo
- {
- char x[2];
- };
+struct TraitResultYes
+{
+ char x;
+};
+struct TraitResultNo
+{
+ char x[2];
+};
- template <typename B, typename D>
- struct IsBaseOfTraitHost
- {
- operator B*() const { return nullptr; }
- operator D*() { return nullptr; }
- };
+template<typename B, typename D>
+struct IsBaseOfTraitHost
+{
+ operator B*() const { return nullptr; }
+ operator D*() { return nullptr; }
+};
- template <typename B, typename D>
- struct IsBaseOf
- {
- template <typename T>
- static TraitResultYes Check(D*, T) { return TraitResultYes(); }
- static TraitResultNo Check(B*, int) { return TraitResultNo(); }
- enum { Value = sizeof(Check(IsBaseOfTraitHost<B, D>(), int())) == sizeof(TraitResultYes) };
- };
+template<typename B, typename D>
+struct IsBaseOf
+{
+ template<typename T>
+ static TraitResultYes Check(D*, T)
+ {
+ return TraitResultYes();
+ }
+ static TraitResultNo Check(B*, int) { return TraitResultNo(); }
+ enum
+ {
+ Value = sizeof(Check(IsBaseOfTraitHost<B, D>(), int())) == sizeof(TraitResultYes)
+ };
+};
- template<bool B, class T = void>
- struct EnableIf {};
+template<bool B, class T = void>
+struct EnableIf
+{
+};
- template<class T>
- struct EnableIf<true, T> { typedef T type; };
+template<class T>
+struct EnableIf<true, T>
+{
+ typedef T type;
+};
- template <typename B, typename D>
- struct IsConvertible
- {
- static TraitResultYes Use(B) { return TraitResultYes(); };
- static TraitResultNo Use(...) { return TraitResultNo(); };
- enum { Value = sizeof(Use(*(D*)(nullptr))) == sizeof(TraitResultYes) };
- };
-}
+template<typename B, typename D>
+struct IsConvertible
+{
+ static TraitResultYes Use(B) { return TraitResultYes(); };
+ static TraitResultNo Use(...) { return TraitResultNo(); };
+ enum
+ {
+ Value = sizeof(Use(*(D*)(nullptr))) == sizeof(TraitResultYes)
+ };
+};
+} // namespace Slang
#endif
diff --git a/source/core/slang-uint-set.cpp b/source/core/slang-uint-set.cpp
index 457915449..ec086c5de 100644
--- a/source/core/slang-uint-set.cpp
+++ b/source/core/slang-uint-set.cpp
@@ -40,13 +40,14 @@ HashCode UIntSet::getHashCode() const
{
int rs = 0;
for (auto val : m_buffer)
- rs ^= val;
+ rs ^= val;
return rs;
}
void UIntSet::resizeAndClear(UInt val)
{
- // TODO(JS): This could be faster in that if the resize is larger the additional area is cleared twice
+ // TODO(JS): This could be faster in that if the resize is larger the additional area is cleared
+ // twice
resize(val);
clear();
}
@@ -86,7 +87,9 @@ void UIntSet::unionWith(const UIntSet& set)
}
if (set.m_buffer.getCount() > m_buffer.getCount())
- m_buffer.addRange(set.m_buffer.getBuffer() + m_buffer.getCount(), set.m_buffer.getCount() - m_buffer.getCount());
+ m_buffer.addRange(
+ set.m_buffer.getBuffer() + m_buffer.getCount(),
+ set.m_buffer.getCount() - m_buffer.getCount());
}
bool UIntSet::operator==(const UIntSet& set) const
@@ -98,16 +101,19 @@ bool UIntSet::operator==(const UIntSet& set) const
const auto bElems = set.m_buffer.getBuffer();
const Index minCount = Math::Min(aCount, bCount);
-
- return ::memcmp(aElems, bElems, minCount*sizeof(Element)) == 0 &&
- _areAllZero(aElems + minCount, aCount - minCount) &&
- _areAllZero(bElems + minCount, bCount - minCount);
+
+ return ::memcmp(aElems, bElems, minCount * sizeof(Element)) == 0 &&
+ _areAllZero(aElems + minCount, aCount - minCount) &&
+ _areAllZero(bElems + minCount, bCount - minCount);
}
void UIntSet::intersectWith(const UIntSet& set)
{
if (set.m_buffer.getCount() < m_buffer.getCount())
- ::memset(m_buffer.getBuffer() + set.m_buffer.getCount(), 0, (m_buffer.getCount() - set.m_buffer.getCount()) * sizeof(Element));
+ ::memset(
+ m_buffer.getBuffer() + set.m_buffer.getCount(),
+ 0,
+ (m_buffer.getCount() - set.m_buffer.getCount()) * sizeof(Element));
const Index minCount = Math::Min(set.m_buffer.getCount(), m_buffer.getCount());
for (Index i = 0; i < minCount; i++)
@@ -125,9 +131,10 @@ void UIntSet::subtractWith(const UIntSet& set)
}
}
-/* static */void UIntSet::calcUnion(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2)
+/* static */ void UIntSet::calcUnion(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2)
{
- outRs.resizeBackingBufferDirectly(Math::Max(set1.m_buffer.getCount(), set2.m_buffer.getCount()));
+ outRs.resizeBackingBufferDirectly(
+ Math::Max(set1.m_buffer.getCount(), set2.m_buffer.getCount()));
outRs.clear();
for (Index i = 0; i < set1.m_buffer.getCount(); i++)
outRs.m_buffer[i] |= set1.m_buffer[i];
@@ -135,7 +142,10 @@ void UIntSet::subtractWith(const UIntSet& set)
outRs.m_buffer[i] |= set2.m_buffer[i];
}
-/* static */void UIntSet::calcIntersection(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2)
+/* static */ void UIntSet::calcIntersection(
+ UIntSet& outRs,
+ const UIntSet& set1,
+ const UIntSet& set2)
{
const Index minCount = Math::Min(set1.m_buffer.getCount(), set2.m_buffer.getCount());
outRs.resizeBackingBufferDirectly(minCount);
@@ -144,7 +154,7 @@ void UIntSet::subtractWith(const UIntSet& set)
outRs.m_buffer[i] = set1.m_buffer[i] & set2.m_buffer[i];
}
-/* static */void UIntSet::calcSubtract(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2)
+/* static */ void UIntSet::calcSubtract(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2)
{
outRs.resizeBackingBufferDirectly(set1.m_buffer.getCount());
@@ -153,7 +163,7 @@ void UIntSet::subtractWith(const UIntSet& set)
outRs.m_buffer[i] = set1.m_buffer[i] & (~set2.m_buffer[i]);
}
-/* static */bool UIntSet::hasIntersection(const UIntSet& set1, const UIntSet& set2)
+/* static */ bool UIntSet::hasIntersection(const UIntSet& set1, const UIntSet& set2)
{
const Index minCount = Math::Min(set1.m_buffer.getCount(), set2.m_buffer.getCount());
for (Index i = 0; i < minCount; i++)
@@ -168,7 +178,8 @@ Index UIntSet::countElements() const
{
// TODO: This can be made faster using SIMD intrinsics to count set bits.
uint64_t tmp;
- constexpr Index loopSize = ((sizeof(Element) / sizeof(tmp)) != 0) ? sizeof(Element) / sizeof(tmp) : 1;
+ constexpr Index loopSize =
+ ((sizeof(Element) / sizeof(tmp)) != 0) ? sizeof(Element) / sizeof(tmp) : 1;
Index count = 0;
for (auto index = 0; index < this->m_buffer.getCount(); index++)
{
@@ -183,5 +194,4 @@ Index UIntSet::countElements() const
return count;
}
-}
-
+} // namespace Slang
diff --git a/source/core/slang-uint-set.h b/source/core/slang-uint-set.h
index 3531e5cfb..ef2668d5a 100644
--- a/source/core/slang-uint-set.h
+++ b/source/core/slang-uint-set.h
@@ -1,10 +1,10 @@
#ifndef SLANG_CORE_UINT_SET_H
#define SLANG_CORE_UINT_SET_H
-#include "slang-list.h"
-#include "slang-math.h"
#include "slang-common.h"
#include "slang-hash.h"
+#include "slang-list.h"
+#include "slang-math.h"
#if defined(_MSC_VER)
#include <intrin.h>
@@ -34,32 +34,36 @@ static inline Index bitscanForward(uint64_t in)
// check for 0s in 0bit->31bit. If all 0's, check for 0s in 32bit->63bit
if (_BitScanForward((unsigned long*)&out, *(((uint32_t*)&in))))
return Index(out);
- _BitScanForward((unsigned long*)&out, *(((uint32_t*)&in)+1));
- return Index(out)+32;
-#endif// #ifdef _WIN64
+ _BitScanForward((unsigned long*)&out, *(((uint32_t*)&in) + 1));
+ return Index(out) + 32;
+#endif // #ifdef _WIN64
-#else
+#else
return Index(__builtin_ctzll(in));
-#endif// #if defined(_MSC_VER)
+#endif // #if defined(_MSC_VER)
}
/* Hold a set of UInt values. Implementation works by storing as a bit per value */
/// UIntSet is essentially a Element[], where each Element is `b` bits big.
-/// Each index has `b` number of integers. If the bit is 1, we have an element there.
+/// Each index has `b` number of integers. If the bit is 1, we have an element there.
/// Value of each element is equal to the binary offset from Element[0], bit 0.
class UIntSet
{
public:
typedef UIntSet ThisType;
- typedef uint64_t Element; ///< Type that holds the bits to say if value is present
-
- constexpr static Index kElementSize = sizeof(Element) * 8; ///< The number of bits in an element. This also determines how many values a element can hold.
+ typedef uint64_t Element; ///< Type that holds the bits to say if value is present
+
+ constexpr static Index kElementSize =
+ sizeof(Element) * 8; ///< The number of bits in an element. This also determines how many
+ ///< values a element can hold.
constexpr static Index kElementMask = kElementSize - 1; ///< Mask to get shift from an index
- constexpr static Index kElementShift = intLog2(sizeof(Element)*8); ///< How many bits to shift to get Element index from an index. 5 for 2^5=32 elements in a uint32_t. 6 for 2^6=64 in a uint64_t.
+ constexpr static Index kElementShift = intLog2(
+ sizeof(Element) * 8); ///< How many bits to shift to get Element index from an index. 5 for
+ ///< 2^5=32 elements in a uint32_t. 6 for 2^6=64 in a uint64_t.
UIntSet() {}
UIntSet(const UIntSet& other) { m_buffer = other.m_buffer; }
- UIntSet(UIntSet && other) { *this = (_Move(other)); }
+ UIntSet(UIntSet&& other) { *this = (_Move(other)); }
UIntSet(UInt maxVal) { resizeAndClear(maxVal); }
UIntSet& operator=(UIntSet&& other);
@@ -72,65 +76,66 @@ public:
const List<Element>& getBuffer() const { return m_buffer; }
- /// Resize such that val can be stored and clear contents
+ /// Resize such that val can be stored and clear contents
void resizeAndClear(UInt val);
- /// Set all of the values up to count, as set
+ /// Set all of the values up to count, as set
void setAll();
- /// Resize (but maintain contents) up to bit size.
- /// NOTE! That since storage is in Element blocks, it may mean some values after size are set (up to the Element boundary)
+ /// Resize (but maintain contents) up to bit size.
+ /// NOTE! That since storage is in Element blocks, it may mean some values after size are set
+ /// (up to the Element boundary)
void resize(UInt size);
void resizeBackingBufferDirectly(Index size);
- /// Clear all of the contents (by clearing the bits)
+ /// Clear all of the contents (by clearing the bits)
void clear();
- /// Clear all the contents and free memory
+ /// Clear all the contents and free memory
void clearAndDeallocate();
- /// Add a value
+ /// Add a value
inline void add(UInt val);
inline void add(const UIntSet& val);
inline void addRange(const List<UInt>& other);
inline void addRawElement(Element val, Index bitOffset);
- /// Remove a value
+ /// Remove a value
inline void remove(UInt val);
- /// Returns true if the value is present
+ /// Returns true if the value is present
inline bool contains(UInt val) const;
inline bool contains(const UIntSet& set) const;
- /// ==
+ /// ==
bool operator==(const UIntSet& set) const;
- /// !=
+ /// !=
bool operator!=(const UIntSet& set) const { return !(*this == set); }
- /// Store the union between this and set
+ /// Store the union between this and set
void unionWith(const UIntSet& set);
- /// Store the intersection between this and set
+ /// Store the intersection between this and set
void intersectWith(const UIntSet& set);
- /// Store the subtraction between this and set
+ /// Store the subtraction between this and set
void subtractWith(const UIntSet& set);
- ///
+ ///
bool isEmpty() const;
- /// Swap this with rhs
+ /// Swap this with rhs
void swapWith(ThisType& rhs) { m_buffer.swapWith(rhs.m_buffer); }
template<typename T>
List<T> getElements() const;
Index countElements() const;
- /// Store the union of set1 and set2 in outRs
+ /// Store the union of set1 and set2 in outRs
static void calcUnion(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2);
- /// Store the intersection of set1 and set2 in outRs
+ /// Store the intersection of set1 and set2 in outRs
static void calcIntersection(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2);
- /// Store the subtraction of set2 from set1 in outRs
+ /// Store the subtraction of set2 from set1 in outRs
static void calcSubtract(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2);
- /// Returns true if set1 and set2 have a same value set (ie there is an intersection)
+ /// Returns true if set1 and set2 have a same value set (ie there is an intersection)
static bool hasIntersection(const UIntSet& set1, const UIntSet& set2);
/// Get LSB Zero of UIntSet. LSB Zero is the smallest value missing from this UIntSet.
@@ -139,6 +144,7 @@ public:
struct Iterator
{
friend class UIntSet;
+
private:
const List<Element>* m_context;
Index m_block = 0;
@@ -151,16 +157,10 @@ public:
m_processedElement &= m_processedElement - 1;
}
- Iterator(const List<Element>* context)
- {
- m_context = context;
- }
- public:
+ Iterator(const List<Element>* context) { m_context = context; }
- Element operator*()
- {
- return Element(m_LSB + (kElementSize * m_block));
- }
+ public:
+ Element operator*() { return Element(m_LSB + (kElementSize * m_block)); }
Iterator& operator++()
{
@@ -176,19 +176,13 @@ public:
clearLSB();
return *this;
}
- Iterator& operator++(int)
- {
- return ++(*this);
- }
+ Iterator& operator++(int) { return ++(*this); }
bool operator==(const Iterator& other) const
{
- return other.m_block == this->m_block
- && other.m_processedElement == this->m_processedElement;
- }
- bool operator!=(const Iterator& other) const
- {
- return !(other == *this);
+ return other.m_block == this->m_block &&
+ other.m_processedElement == this->m_processedElement;
}
+ bool operator!=(const Iterator& other) const { return !(other == *this); }
};
Iterator begin() const
{
@@ -214,10 +208,7 @@ public:
return tmp;
}
- bool areAllZero()
- {
- return _areAllZero(m_buffer.getBuffer(), m_buffer.getCount());
- }
+ bool areAllZero() { return _areAllZero(m_buffer.getBuffer(), m_buffer.getCount()); }
protected:
static bool _areAllZero(const UIntSet::Element* elems, Index count)
@@ -250,7 +241,7 @@ inline bool UIntSet::contains(UInt val) const
{
const Index idx = Index(val >> kElementShift);
return idx < m_buffer.getCount() &&
- ((m_buffer[idx] & (Element(1) << (val & kElementMask))) != 0);
+ ((m_buffer[idx] & (Element(1) << (val & kElementMask))) != 0);
}
// --------------------------------------------------------------------------
@@ -313,8 +304,8 @@ inline void UIntSet::addRange(const List<UInt>& other)
inline void UIntSet::addRawElement(Element other, Index elementIndex)
{
- if(this->m_buffer.getCount() <= elementIndex)
- resizeBackingBufferDirectly(elementIndex+1);
+ if (this->m_buffer.getCount() <= elementIndex)
+ resizeBackingBufferDirectly(elementIndex + 1);
m_buffer[elementIndex] |= other;
}
@@ -325,7 +316,8 @@ List<T> UIntSet::getElements() const
if (count == 0)
return {};
- // Specific path for uint64_t. If using SIMD we should not use this path due to larger data types.
+ // Specific path for uint64_t. If using SIMD we should not use this path due to larger data
+ // types.
List<T> elements;
elements.reserve(count);
@@ -341,5 +333,5 @@ List<T> UIntSet::getElements() const
return elements;
}
-}
+} // namespace Slang
#endif
diff --git a/source/core/slang-virtual-object-pool.h b/source/core/slang-virtual-object-pool.h
index c1247acb7..6e8682c16 100644
--- a/source/core/slang-virtual-object-pool.h
+++ b/source/core/slang-virtual-object-pool.h
@@ -4,10 +4,10 @@
namespace Slang
{
- /// A virtual free-list allocater.
- /// This class doesn't actually allocates memory, instead it operates on a
- /// virtual integer space. Can be used to implement various types of object pools
- /// that needs to support contiguous allocations of more than one elements.
+/// A virtual free-list allocater.
+/// This class doesn't actually allocates memory, instead it operates on a
+/// virtual integer space. Can be used to implement various types of object pools
+/// that needs to support contiguous allocations of more than one elements.
class VirtualObjectPool
{
public:
diff --git a/source/core/slang-writer.cpp b/source/core/slang-writer.cpp
index 74a39f871..eb315323c 100644
--- a/source/core/slang-writer.cpp
+++ b/source/core/slang-writer.cpp
@@ -1,4 +1,4 @@
-#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
#include "slang-writer.h"
@@ -9,9 +9,9 @@
// output when writing assembly dumps.
#include <fcntl.h>
#ifdef _WIN32
-# include <io.h>
+#include <io.h>
#else
-# include <unistd.h>
+#include <unistd.h>
#endif
#include <stdarg.h>
@@ -64,7 +64,9 @@ SlangResult WriterHelper::put(const UnownedStringSlice& text)
ISlangUnknown* BaseWriter::getInterface(const Guid& guid)
{
- return (guid == ISlangUnknown::getTypeGuid() || guid == ISlangWriter::getTypeGuid()) ? static_cast<ISlangWriter*>(this) : nullptr;
+ return (guid == ISlangUnknown::getTypeGuid() || guid == ISlangWriter::getTypeGuid())
+ ? static_cast<ISlangWriter*>(this)
+ : nullptr;
}
/* !!!!!!!!!!!!!!!!!!!!!!!!! AppendBufferWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
@@ -76,7 +78,8 @@ SLANG_NO_THROW char* SLANG_MCALL AppendBufferWriter::beginAppendBuffer(size_t ma
return m_appendBuffer.getBuffer();
}
-SLANG_NO_THROW SlangResult SLANG_MCALL AppendBufferWriter::endAppendBuffer(char* buffer, size_t numChars)
+SLANG_NO_THROW SlangResult SLANG_MCALL
+AppendBufferWriter::endAppendBuffer(char* buffer, size_t numChars)
{
SLANG_ASSERT(m_appendBuffer.getBuffer() == buffer && buffer + numChars <= m_appendBuffer.end());
// Do the actual write
@@ -102,7 +105,8 @@ SlangResult CallbackWriter::write(const char* chars, size_t numChars)
{
char* appendBuffer = m_appendBuffer.getBuffer();
// See if it's from an append buffer
- if (chars >= appendBuffer && (chars + numChars) < (appendBuffer + m_appendBuffer.getCount()))
+ if (chars >= appendBuffer &&
+ (chars + numChars) < (appendBuffer + m_appendBuffer.getCount()))
{
// Set terminating 0
appendBuffer[(chars + numChars) - appendBuffer] = 0;
@@ -153,7 +157,7 @@ void FileWriter::flush()
::fflush(m_file);
}
-/* static */bool FileWriter::isConsole(FILE* file)
+/* static */ bool FileWriter::isConsole(FILE* file)
{
const int stdoutFileDesc = _fileno(file);
return _isatty(stdoutFileDesc) != 0;
@@ -164,21 +168,25 @@ SlangResult FileWriter::setMode(SlangWriterMode mode)
switch (mode)
{
case SLANG_WRITER_MODE_BINARY:
- {
+ {
#ifdef _WIN32
- int stdoutFileDesc = _fileno(m_file);
- _setmode(stdoutFileDesc, _O_BINARY);
- return SLANG_OK;
+ int stdoutFileDesc = _fileno(m_file);
+ _setmode(stdoutFileDesc, _O_BINARY);
+ return SLANG_OK;
#else
- break;
+ break;
#endif
- }
+ }
default: break;
}
return SLANG_FAIL;
}
-/* static */SlangResult FileWriter::create(const char* filePath, const char* writeOptions, WriterFlags flags, ComPtr<ISlangWriter>& outWriter)
+/* static */ SlangResult FileWriter::create(
+ const char* filePath,
+ const char* writeOptions,
+ WriterFlags flags,
+ ComPtr<ISlangWriter>& outWriter)
{
flags &= ~WriterFlag::IsUnowned;
@@ -215,5 +223,4 @@ SlangResult StringWriter::write(const char* chars, size_t numChars)
return SLANG_OK;
}
-}
-
+} // namespace Slang
diff --git a/source/core/slang-writer.h b/source/core/slang-writer.h
index e29939161..c6822a6e3 100644
--- a/source/core/slang-writer.h
+++ b/source/core/slang-writer.h
@@ -1,12 +1,10 @@
#ifndef SLANG_CORE_WRITER_H
#define SLANG_CORE_WRITER_H
-#include "slang-string.h"
-
#include "slang-com-helper.h"
#include "slang-com-ptr.h"
-
#include "slang-list.h"
+#include "slang-string.h"
#include <mutex>
@@ -20,12 +18,18 @@ public:
SlangResult print(const char* format, ...);
SlangResult put(const char* text);
SlangResult put(const UnownedStringSlice& text);
- SLANG_FORCE_INLINE SlangResult write(const char* chars, size_t numChars) { return m_writer->write(chars, numChars); }
+ SLANG_FORCE_INLINE SlangResult write(const char* chars, size_t numChars)
+ {
+ return m_writer->write(chars, numChars);
+ }
SLANG_FORCE_INLINE void flush() { m_writer->flush(); }
-
- ISlangWriter* getWriter() const { return m_writer; }
- WriterHelper(ISlangWriter* writer) :m_writer(writer) {}
+ ISlangWriter* getWriter() const { return m_writer; }
+
+ WriterHelper(ISlangWriter* writer)
+ : m_writer(writer)
+ {
+ }
protected:
ISlangWriter* m_writer;
@@ -33,13 +37,14 @@ protected:
struct WriterFlag
{
- enum Enum :uint32_t
+ enum Enum : uint32_t
{
- IsStatic = 0x1, ///< Means non ref counted
- IsConsole = 0x2, ///< True if console
- IsUnowned = 0x4, ///< True if doesn't own contained type
- AutoFlush = 0x8, ///< Automatically flushes after every call
+ IsStatic = 0x1, ///< Means non ref counted
+ IsConsole = 0x2, ///< True if console
+ IsUnowned = 0x4, ///< True if doesn't own contained type
+ AutoFlush = 0x8, ///< Automatically flushes after every call
};
+
private:
WriterFlag() = delete;
};
@@ -51,24 +56,36 @@ public:
// ISlangUnknown
SLANG_REF_OBJECT_IUNKNOWN_QUERY_INTERFACE
SLANG_REF_OBJECT_IUNKNOWN_ADD_REF
- SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return (m_flags & WriterFlag::IsStatic) ? (uint32_t)decreaseReference() : (uint32_t)releaseReference(); }
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE
+ {
+ return (m_flags & WriterFlag::IsStatic) ? (uint32_t)decreaseReference()
+ : (uint32_t)releaseReference();
+ }
// ISlangWriter - default impl
SLANG_NO_THROW virtual void SLANG_MCALL flush() SLANG_OVERRIDE {}
- SLANG_NO_THROW virtual bool SLANG_MCALL isConsole() SLANG_OVERRIDE { return (m_flags & WriterFlag::IsConsole) != 0; }
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL setMode(SlangWriterMode mode) SLANG_OVERRIDE { SLANG_UNUSED(mode); return SLANG_FAIL; }
+ SLANG_NO_THROW virtual bool SLANG_MCALL isConsole() SLANG_OVERRIDE
+ {
+ return (m_flags & WriterFlag::IsConsole) != 0;
+ }
+ SLANG_NO_THROW virtual SlangResult SLANG_MCALL setMode(SlangWriterMode mode) SLANG_OVERRIDE
+ {
+ SLANG_UNUSED(mode);
+ return SLANG_FAIL;
+ }
- BaseWriter(WriterFlags flags) :
- m_flags(flags)
+ BaseWriter(WriterFlags flags)
+ : m_flags(flags)
{
}
protected:
- ISlangUnknown * getInterface(const Guid& guid);
+ ISlangUnknown* getInterface(const Guid& guid);
WriterFlags m_flags;
};
-/* Implemented the append buffer part of the writer, such that calls to begin/endAppendBuffer are transformed into appropriate calls to write method */
+/* Implemented the append buffer part of the writer, such that calls to begin/endAppendBuffer are
+ * transformed into appropriate calls to write method */
class AppendBufferWriter : public BaseWriter
{
public:
@@ -76,11 +93,13 @@ public:
// ISlangWriter default impl for appendBuffer
SLANG_NO_THROW char* SLANG_MCALL beginAppendBuffer(size_t maxNumChars) SLANG_OVERRIDE;
- SLANG_NO_THROW SlangResult SLANG_MCALL endAppendBuffer(char* buffer, size_t numChars) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL endAppendBuffer(char* buffer, size_t numChars)
+ SLANG_OVERRIDE;
- AppendBufferWriter(WriterFlags flags) :
- Parent(flags)
- {}
+ AppendBufferWriter(WriterFlags flags)
+ : Parent(flags)
+ {
+ }
protected:
List<char> m_appendBuffer;
@@ -93,16 +112,15 @@ public:
typedef AppendBufferWriter Parent;
// ISlangWriter
SLANG_NO_THROW char* SLANG_MCALL beginAppendBuffer(size_t maxNumChars) SLANG_OVERRIDE;
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars) SLANG_OVERRIDE;
-
- CallbackWriter(SlangDiagnosticCallback callback, const void* data, WriterFlags flags) :
- Parent(flags),
- m_callback(callback),
- m_data(data)
- {}
+ SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars)
+ SLANG_OVERRIDE;
+
+ CallbackWriter(SlangDiagnosticCallback callback, const void* data, WriterFlags flags)
+ : Parent(flags), m_callback(callback), m_data(data)
+ {
+ }
protected:
-
SlangDiagnosticCallback m_callback;
const void* m_data;
};
@@ -112,26 +130,46 @@ class FileWriter : public AppendBufferWriter
public:
typedef AppendBufferWriter Parent;
// ISlangWriter
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars)
+ SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL flush() SLANG_OVERRIDE;
SLANG_NO_THROW virtual SlangResult SLANG_MCALL setMode(SlangWriterMode mode) SLANG_OVERRIDE;
static bool isConsole(FILE* file);
- static WriterFlags getDefaultFlags(FILE* file) { return isConsole(file) ? WriterFlags(WriterFlag::IsConsole) : 0; }
-
- /// Ctor
- FileWriter(FILE* file, WriterFlags flags) :
- Parent(flags | getDefaultFlags(file)),
- m_file(file)
- {}
+ static WriterFlags getDefaultFlags(FILE* file)
+ {
+ return isConsole(file) ? WriterFlags(WriterFlag::IsConsole) : 0;
+ }
- ///
- static SlangResult create(const char* filePath, const char* writeOptions, WriterFlags flags, ComPtr<ISlangWriter>& outWriter);
+ /// Ctor
+ FileWriter(FILE* file, WriterFlags flags)
+ : Parent(flags | getDefaultFlags(file)), m_file(file)
+ {
+ }
- static SlangResult createBinary(const char* filePath, WriterFlags flags, ComPtr<ISlangWriter>& outWriter) { return create(filePath, "wb", flags, outWriter); }
- static SlangResult createText(const char* filePath, WriterFlags flags, ComPtr<ISlangWriter>& outWriter) { return create(filePath, "w", flags, outWriter); }
+ ///
+ static SlangResult create(
+ const char* filePath,
+ const char* writeOptions,
+ WriterFlags flags,
+ ComPtr<ISlangWriter>& outWriter);
+
+ static SlangResult createBinary(
+ const char* filePath,
+ WriterFlags flags,
+ ComPtr<ISlangWriter>& outWriter)
+ {
+ return create(filePath, "wb", flags, outWriter);
+ }
+ static SlangResult createText(
+ const char* filePath,
+ WriterFlags flags,
+ ComPtr<ISlangWriter>& outWriter)
+ {
+ return create(filePath, "w", flags, outWriter);
+ }
- /// Dtor
+ /// Dtor
~FileWriter();
protected:
@@ -144,14 +182,16 @@ public:
typedef BaseWriter Parent;
// ISlangWriter
SLANG_NO_THROW char* SLANG_MCALL beginAppendBuffer(size_t maxNumChars) SLANG_OVERRIDE;
- SLANG_NO_THROW SlangResult SLANG_MCALL endAppendBuffer(char* buffer, size_t numChars) SLANG_OVERRIDE;
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars) SLANG_OVERRIDE;
-
- /// Ctor
- StringWriter(StringBuilder* builder, WriterFlags flags) :
- Parent(flags),
- m_builder(builder)
- {}
+ SLANG_NO_THROW SlangResult SLANG_MCALL endAppendBuffer(char* buffer, size_t numChars)
+ SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars)
+ SLANG_OVERRIDE;
+
+ /// Ctor
+ StringWriter(StringBuilder* builder, WriterFlags flags)
+ : Parent(flags), m_builder(builder)
+ {
+ }
~StringWriter() {}
protected:
@@ -163,13 +203,20 @@ class NullWriter : public AppendBufferWriter
public:
typedef AppendBufferWriter Parent;
// ISlangWriter
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars) SLANG_OVERRIDE { SLANG_UNUSED(chars); SLANG_UNUSED(numChars); return SLANG_OK; }
+ SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars)
+ SLANG_OVERRIDE
+ {
+ SLANG_UNUSED(chars);
+ SLANG_UNUSED(numChars);
+ return SLANG_OK;
+ }
/// Ctor
- NullWriter(WriterFlags flags) :
- Parent(flags)
- {}
+ NullWriter(WriterFlags flags)
+ : Parent(flags)
+ {
+ }
};
-}
+} // namespace Slang
#endif // SLANG_TEXT_WRITER_H
diff --git a/source/core/slang-zip-file-system.cpp b/source/core/slang-zip-file-system.cpp
index 02d4c9a2b..b3c50ab57 100644
--- a/source/core/slang-zip-file-system.cpp
+++ b/source/core/slang-zip-file-system.cpp
@@ -1,68 +1,86 @@
#include "slang-zip-file-system.h"
+#include "slang-blob.h"
#include "slang-com-helper.h"
#include "slang-com-ptr.h"
-
+#include "slang-implicit-directory-collector.h"
#include "slang-io.h"
-#include "slang-string-util.h"
-#include "slang-blob.h"
+#include "slang-riff.h"
#include "slang-string-slice-pool.h"
+#include "slang-string-util.h"
#include "slang-uint-set.h"
-#include "slang-riff.h"
-
-#include "slang-implicit-directory-collector.h"
#include <miniz.h>
namespace Slang
{
-class ZipFileSystemImpl : public ISlangMutableFileSystem, public IArchiveFileSystem, public ComBaseObject
+class ZipFileSystemImpl : public ISlangMutableFileSystem,
+ public IArchiveFileSystem,
+ public ComBaseObject
{
public:
- // ISlangUnknown
+ // ISlangUnknown
SLANG_COM_BASE_IUNKNOWN_ALL
// ISlangCastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// ISlangFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadFile(char const* path, ISlangBlob** outBlob)
+ SLANG_OVERRIDE;
// ISlangFileSystemExt
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getFileUniqueIdentity(const char* path, ISlangBlob** uniqueIdentityOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPathType(const char* path, SlangPathType* pathTypeOut) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getFileUniqueIdentity(const char* path, ISlangBlob** uniqueIdentityOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPathType(const char* path, SlangPathType* pathTypeOut) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ getPath(PathKind pathKind, const char* path, ISlangBlob** outPath) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL clearCache() SLANG_OVERRIDE {}
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE { return OSPathKind::None; }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW OSPathKind SLANG_MCALL getOSPathKind() SLANG_OVERRIDE
+ {
+ return OSPathKind::None;
+ }
// ISlangModifyableFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFile(const char* path, const void* data, size_t size) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ saveFileBlob(const char* path, ISlangBlob* dataBlob) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL remove(const char* path) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL createDirectory(const char* path) SLANG_OVERRIDE;
// IArchiveFileSystem
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadArchive(const void* archive, size_t archiveSizeInBytes) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL storeArchive(bool blobOwnsContent, ISlangBlob** outBlob) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW void SLANG_MCALL setCompressionStyle(const CompressionStyle& style) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ loadArchive(const void* archive, size_t archiveSizeInBytes) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ storeArchive(bool blobOwnsContent, ISlangBlob** outBlob) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW void SLANG_MCALL setCompressionStyle(const CompressionStyle& style)
+ SLANG_OVERRIDE;
ZipFileSystemImpl();
~ZipFileSystemImpl();
protected:
-
enum class Mode
{
- None, // m_archive is not initialized
- Read, // m_archive is a reader
- ReadWrite, // m_archive is a writer (that can be read from)
+ None, // m_archive is not initialized
+ Read, // m_archive is a reader
+ ReadWrite, // m_archive is a writer (that can be read from)
};
SlangResult _requireMode(Mode mode);
- /// Do the mode change.
+ /// Do the mode change.
SlangResult _requireModeImpl(Mode newMode);
bool _hasArchive() { return m_mode != Mode::None; }
@@ -72,14 +90,16 @@ protected:
SlangResult _copyToAndInitWriter(mz_zip_archive& outWriter);
- /// Returns SLANG_E_NOT_FOUND if no directory or contents found
- /// terminationState controls when search terminates. If State::Undefined, will enumerate everything.
- /// If outContents not set, will just determine if the directory exists
- SlangResult _getPathContents(ImplicitDirectoryCollector::State terminationState, ImplicitDirectoryCollector* outCollector);
+ /// Returns SLANG_E_NOT_FOUND if no directory or contents found
+ /// terminationState controls when search terminates. If State::Undefined, will enumerate
+ /// everything. If outContents not set, will just determine if the directory exists
+ SlangResult _getPathContents(
+ ImplicitDirectoryCollector::State terminationState,
+ ImplicitDirectoryCollector* outCollector);
void _rebuildMap();
- /// Returns true if the named item is at the index
+ /// Returns true if the named item is at the index
UnownedStringSlice _getPathAtIndex(Index index);
void* getInterface(const Guid& guid);
@@ -99,19 +119,18 @@ protected:
mz_file_read_func m_readFunc;
- mz_zip_archive m_archive;
+ mz_zip_archive m_archive;
};
void* ZipFileSystemImpl::getInterface(const Guid& guid)
{
- if ( guid == ISlangUnknown::getTypeGuid() ||
- guid == ISlangCastable::getTypeGuid())
+ if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangCastable::getTypeGuid())
{
return static_cast<ISlangMutableFileSystem*>(this);
}
- else if (guid == ISlangFileSystem::getTypeGuid() ||
- guid == ISlangFileSystemExt::getTypeGuid() ||
- guid == ISlangMutableFileSystem::getTypeGuid())
+ else if (
+ guid == ISlangFileSystem::getTypeGuid() || guid == ISlangFileSystemExt::getTypeGuid() ||
+ guid == ISlangMutableFileSystem::getTypeGuid())
{
return static_cast<ISlangMutableFileSystem*>(this);
}
@@ -137,8 +156,9 @@ void* ZipFileSystemImpl::castAs(const Guid& guid)
return getObject(guid);
}
-// This is a very awkward hack to make it so we can get a read func, without having to implement all of the tracking etc.
-// All this does is create an empty zip, convert into a reader, and then grab the read function
+// This is a very awkward hack to make it so we can get a read func, without having to implement all
+// of the tracking etc. All this does is create an empty zip, convert into a reader, and then grab
+// the read function
static mz_file_read_func _calcReadFunc()
{
mz_zip_archive archive;
@@ -169,16 +189,16 @@ static mz_file_read_func _getReadFunc()
return readFunc;
}
-ZipFileSystemImpl::ZipFileSystemImpl():
- m_mode(Mode::None)
+ZipFileSystemImpl::ZipFileSystemImpl()
+ : m_mode(Mode::None)
{
- m_readFunc = _getReadFunc();
+ m_readFunc = _getReadFunc();
}
- ZipFileSystemImpl::~ZipFileSystemImpl()
- {
- _requireMode(Mode::None);
- }
+ZipFileSystemImpl::~ZipFileSystemImpl()
+{
+ _requireMode(Mode::None);
+}
void ZipFileSystemImpl::_rebuildMap()
{
@@ -231,13 +251,13 @@ SlangResult ZipFileSystemImpl::_copyToAndInitWriter(mz_zip_archive& outWriter)
mz_zip_zero_struct(&outWriter);
switch (m_mode)
{
- case Mode::None:
+ case Mode::None:
{
_initReadWrite(outWriter);
return SLANG_OK;
}
- case Mode::Read:
- case Mode::ReadWrite:
+ case Mode::Read:
+ case Mode::ReadWrite:
{
_initReadWrite(outWriter);
@@ -250,14 +270,16 @@ SlangResult ZipFileSystemImpl::_copyToAndInitWriter(mz_zip_archive& outWriter)
continue;
}
- // It's worth noting - it's not clear if this will work, because m_archive might not be a reader, in the miniz docs.
- // If it's a writer, it's not clear how to convert a writer to a reader *selectively* which
- // we require if we are going to lazily handle removals.
+ // It's worth noting - it's not clear if this will work, because m_archive might not
+ // be a reader, in the miniz docs. If it's a writer, it's not clear how to convert a
+ // writer to a reader *selectively* which we require if we are going to lazily
+ // handle removals.
//
- // The fix to make this work is the hack that sets the m_reader, such that in effect the writer is both read and write.
- // That works because the default writer behavior is a single block of memory for the archive, and that is compatible
- // with the reader.
- if (! mz_zip_writer_add_from_zip_reader(&outWriter, &m_archive, i))
+ // The fix to make this work is the hack that sets the m_reader, such that in effect
+ // the writer is both read and write. That works because the default writer behavior
+ // is a single block of memory for the archive, and that is compatible with the
+ // reader.
+ if (!mz_zip_writer_add_from_zip_reader(&outWriter, &m_archive, i))
{
mz_zip_end(&outWriter);
return SLANG_FAIL;
@@ -267,9 +289,9 @@ SlangResult ZipFileSystemImpl::_copyToAndInitWriter(mz_zip_archive& outWriter)
return SLANG_OK;
}
- default: break;
+ default: break;
}
- return SLANG_FAIL;
+ return SLANG_FAIL;
}
SlangResult ZipFileSystemImpl::_requireModeImpl(Mode newMode)
@@ -278,37 +300,37 @@ SlangResult ZipFileSystemImpl::_requireModeImpl(Mode newMode)
switch (m_mode)
{
- case Mode::None:
+ case Mode::None:
{
switch (newMode)
{
- case Mode::Read:
+ case Mode::Read:
{
mz_uint flags = 0;
mz_zip_zero_struct(&m_archive);
mz_zip_reader_init(&m_archive, 0, flags);
break;
}
- case Mode::ReadWrite:
+ case Mode::ReadWrite:
{
_initReadWrite(m_archive);
break;
}
- default: break;
+ default: break;
}
break;
}
- case Mode::Read:
+ case Mode::Read:
{
switch (newMode)
{
- case Mode::None:
+ case Mode::None:
{
m_data.deallocate();
mz_zip_end(&m_archive);
break;
}
- case Mode::ReadWrite:
+ case Mode::ReadWrite:
{
// If nothing is removed, we can just convert
if (m_removedSet.isEmpty())
@@ -343,18 +365,19 @@ SlangResult ZipFileSystemImpl::_requireModeImpl(Mode newMode)
}
break;
}
- case Mode::ReadWrite:
+ case Mode::ReadWrite:
{
switch (newMode)
{
- case Mode::None:
+ case Mode::None:
{
mz_zip_writer_end(&m_archive);
break;
}
- case Mode::Read:
+ case Mode::Read:
{
- // If anything has been removed we copy selectively into a new writer, and then convert that
+ // If anything has been removed we copy selectively into a new writer, and then
+ // convert that
if (!m_removedSet.isEmpty())
{
// There are entries that are deleted... so we need to copy selectively
@@ -378,14 +401,18 @@ SlangResult ZipFileSystemImpl::_requireModeImpl(Mode newMode)
// Read
mz_zip_zero_struct(&m_archive);
- if (!mz_zip_reader_init_mem(&m_archive, m_data.getData(), m_data.getSizeInBytes(), 0))
+ if (!mz_zip_reader_init_mem(
+ &m_archive,
+ m_data.getData(),
+ m_data.getSizeInBytes(),
+ 0))
{
m_data.deallocate();
return SLANG_FAIL;
}
break;
}
- default: break;
+ default: break;
}
}
}
@@ -415,12 +442,15 @@ SlangResult ZipFileSystemImpl::_requireMode(Mode newMode)
SlangResult ZipFileSystemImpl::_getFixedPath(const char* path, String& outPath)
{
StringBuilder simplifiedPath;
- SLANG_RETURN_ON_FAIL(Path::simplify(path, Path::SimplifyStyle::AbsoluteOnlyAndNoRoot, simplifiedPath));
+ SLANG_RETURN_ON_FAIL(
+ Path::simplify(path, Path::SimplifyStyle::AbsoluteOnlyAndNoRoot, simplifiedPath));
outPath = simplifiedPath;
return SLANG_OK;
}
-SlangResult ZipFileSystemImpl::_findEntryIndexFromFixedPath(const String& fixedPath, mz_uint& outIndex)
+SlangResult ZipFileSystemImpl::_findEntryIndexFromFixedPath(
+ const String& fixedPath,
+ mz_uint& outIndex)
{
const Index index = m_pathMap.getValue(fixedPath.getUnownedSlice());
@@ -463,7 +493,12 @@ SlangResult ZipFileSystemImpl::loadFile(char const* path, ISlangBlob** outBlob)
const mz_uint flags = 0;
// Extract to memory
- if (!mz_zip_reader_extract_to_mem(&m_archive, index, alloc.getData(), alloc.getSizeInBytes(), flags))
+ if (!mz_zip_reader_extract_to_mem(
+ &m_archive,
+ index,
+ alloc.getData(),
+ alloc.getSizeInBytes(),
+ flags))
{
return SLANG_FAIL;
}
@@ -499,7 +534,8 @@ SlangResult ZipFileSystemImpl::getPathType(const char* path, SlangPathType* outP
{
// It could be an *implicit* directory (ie as part of a path). So lets look for that...
ImplicitDirectoryCollector collector(fixedPath);
- SLANG_RETURN_ON_FAIL(_getPathContents(ImplicitDirectoryCollector::State::DirectoryExists, &collector));
+ SLANG_RETURN_ON_FAIL(
+ _getPathContents(ImplicitDirectoryCollector::State::DirectoryExists, &collector));
if (collector.getDirectoryExists())
{
*outPathType = SLANG_PATH_TYPE_DIRECTORY;
@@ -514,8 +550,8 @@ SlangResult ZipFileSystemImpl::getPath(PathKind pathKind, const char* path, ISla
{
switch (pathKind)
{
- case PathKind::Display:
- case PathKind::Canonical:
+ case PathKind::Display:
+ case PathKind::Canonical:
{
// Get the fixed path
String fixedPath;
@@ -540,33 +576,39 @@ SlangResult ZipFileSystemImpl::getPath(PathKind pathKind, const char* path, ISla
*outPath = StringUtil::createStringBlob(fixedPath).detach();
return SLANG_OK;
}
- case PathKind::Simplified:
+ case PathKind::Simplified:
{
*outPath = StringUtil::createStringBlob(Path::simplify(path)).detach();
return SLANG_OK;
}
- default: break;
+ default: break;
}
return SLANG_E_NOT_AVAILABLE;
}
-SlangResult ZipFileSystemImpl::getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity)
+SlangResult ZipFileSystemImpl::getFileUniqueIdentity(
+ const char* path,
+ ISlangBlob** outUniqueIdentity)
{
return getPath(PathKind::Canonical, path, outUniqueIdentity);
}
-SlangResult ZipFileSystemImpl::calcCombinedPath(SlangPathType fromPathType, const char* fromPath, const char* path, ISlangBlob** pathOut)
+SlangResult ZipFileSystemImpl::calcCombinedPath(
+ SlangPathType fromPathType,
+ const char* fromPath,
+ const char* path,
+ ISlangBlob** pathOut)
{
String relPath;
switch (fromPathType)
{
- case SLANG_PATH_TYPE_FILE:
+ case SLANG_PATH_TYPE_FILE:
{
relPath = Path::combine(Path::getParentDirectory(fromPath), path);
break;
}
- case SLANG_PATH_TYPE_DIRECTORY:
+ case SLANG_PATH_TYPE_DIRECTORY:
{
relPath = Path::combine(fromPath, path);
break;
@@ -577,7 +619,9 @@ SlangResult ZipFileSystemImpl::calcCombinedPath(SlangPathType fromPathType, cons
return SLANG_OK;
}
-SlangResult ZipFileSystemImpl::_getPathContents(ImplicitDirectoryCollector::State terminationState, ImplicitDirectoryCollector* outCollector)
+SlangResult ZipFileSystemImpl::_getPathContents(
+ ImplicitDirectoryCollector::State terminationState,
+ ImplicitDirectoryCollector* outCollector)
{
if (!_hasArchive())
{
@@ -602,11 +646,13 @@ SlangResult ZipFileSystemImpl::_getPathContents(ImplicitDirectoryCollector::Stat
}
UnownedStringSlice currentPath(fileStat.m_filename);
- SlangPathType pathType = fileStat.m_is_directory ? SLANG_PATH_TYPE_DIRECTORY : SLANG_PATH_TYPE_FILE;
+ SlangPathType pathType =
+ fileStat.m_is_directory ? SLANG_PATH_TYPE_DIRECTORY : SLANG_PATH_TYPE_FILE;
outCollector->addPath(pathType, currentPath);
// If a termination state is defined, and we reach it, we are done
- if (terminationState != ImplicitDirectoryCollector::State::None && outCollector->hasState(terminationState))
+ if (terminationState != ImplicitDirectoryCollector::State::None &&
+ outCollector->hasState(terminationState))
{
return SLANG_OK;
}
@@ -615,7 +661,10 @@ SlangResult ZipFileSystemImpl::_getPathContents(ImplicitDirectoryCollector::Stat
return outCollector->getDirectoryExists() ? SLANG_OK : SLANG_E_NOT_FOUND;
}
-SlangResult ZipFileSystemImpl::enumeratePathContents(const char* path, FileSystemContentsCallBack callback, void* userData)
+SlangResult ZipFileSystemImpl::enumeratePathContents(
+ const char* path,
+ FileSystemContentsCallBack callback,
+ void* userData)
{
if (!_hasArchive())
{
@@ -699,8 +748,9 @@ SlangResult ZipFileSystemImpl::remove(const char* path)
if (fileStat.m_is_directory)
{
// Find the directory contents
- ImplicitDirectoryCollector collector(fixedPath);
- SLANG_RETURN_ON_FAIL(_getPathContents(ImplicitDirectoryCollector::State::HasContent, &collector));
+ ImplicitDirectoryCollector collector(fixedPath);
+ SLANG_RETURN_ON_FAIL(
+ _getPathContents(ImplicitDirectoryCollector::State::HasContent, &collector));
if (collector.hasContent())
{
@@ -744,7 +794,7 @@ SlangResult ZipFileSystemImpl::createDirectory(const char* path)
SLANG_ASSERT(_getPathAtIndex(entryCount) == fixedPath.getUnownedSlice());
// Set the index, that we added at end
- m_pathMap.add(fixedPath.getUnownedSlice(), entryCount);
+ m_pathMap.add(fixedPath.getUnownedSlice(), entryCount);
return SLANG_OK;
}
@@ -755,7 +805,7 @@ SlangResult ZipFileSystemImpl::storeArchive(bool blobOwnsContent, ISlangBlob** o
{
_requireMode(Mode::ReadWrite);
}
-
+
_requireMode(Mode::Read);
ComPtr<ISlangBlob> blob;
@@ -776,7 +826,7 @@ SlangResult ZipFileSystemImpl::storeArchive(bool blobOwnsContent, ISlangBlob** o
SlangResult ZipFileSystemImpl::loadArchive(const void* archive, size_t archiveSizeInBytes)
{
- // Making the mode None empties the archive
+ // Making the mode None empties the archive
SLANG_RETURN_ON_FAIL(_requireMode(Mode::None));
// Store a copy of the archive contents
@@ -806,10 +856,10 @@ void ZipFileSystemImpl::setCompressionStyle(const CompressionStyle& style)
{
switch (style.m_type)
{
- case CompressionStyle::Type::BestSpeed: m_compressionLevel = MZ_BEST_SPEED; break;
- case CompressionStyle::Type::BestCompression: m_compressionLevel = MZ_BEST_COMPRESSION; break;
- case CompressionStyle::Type::Default: m_compressionLevel = MZ_DEFAULT_LEVEL; break;
- case CompressionStyle::Type::Level:
+ case CompressionStyle::Type::BestSpeed: m_compressionLevel = MZ_BEST_SPEED; break;
+ case CompressionStyle::Type::BestCompression: m_compressionLevel = MZ_BEST_COMPRESSION; break;
+ case CompressionStyle::Type::Default: m_compressionLevel = MZ_DEFAULT_LEVEL; break;
+ case CompressionStyle::Type::Level:
{
int level = int(style.m_level * 10.0f + 0.5);
level = (level < 0) ? 0 : level;
@@ -820,13 +870,13 @@ void ZipFileSystemImpl::setCompressionStyle(const CompressionStyle& style)
}
}
-/* static */SlangResult ZipFileSystem::create(ComPtr<ISlangMutableFileSystem>& out)
+/* static */ SlangResult ZipFileSystem::create(ComPtr<ISlangMutableFileSystem>& out)
{
out = new ZipFileSystemImpl;
return SLANG_OK;
}
-/* static */bool ZipFileSystem::isArchive(const void* data, size_t dataSizeInBytes)
+/* static */ bool ZipFileSystem::isArchive(const void* data, size_t dataSizeInBytes)
{
if (dataSizeInBytes < sizeof(FourCC))
{
@@ -839,9 +889,9 @@ void ZipFileSystemImpl::setCompressionStyle(const CompressionStyle& style)
// https://en.wikipedia.org/wiki/List_of_file_signatures
switch (fourCC)
{
- case SLANG_FOUR_CC(0x50, 0x4B, 0x03, 0x04):
- case SLANG_FOUR_CC(0x50, 0x4B, 0x05, 0x06):
- case SLANG_FOUR_CC(0x50, 0x4B, 0x07, 0x08):
+ case SLANG_FOUR_CC(0x50, 0x4B, 0x03, 0x04):
+ case SLANG_FOUR_CC(0x50, 0x4B, 0x05, 0x06):
+ case SLANG_FOUR_CC(0x50, 0x4B, 0x07, 0x08):
{
// It's a zip
return true;
diff --git a/source/core/slang-zip-file-system.h b/source/core/slang-zip-file-system.h
index 120d5003a..6491a6403 100644
--- a/source/core/slang-zip-file-system.h
+++ b/source/core/slang-zip-file-system.h
@@ -1,21 +1,20 @@
#ifndef SLANG_ZIP_FILE_SYSTEM_H
#define SLANG_ZIP_FILE_SYSTEM_H
-#include "slang-basic.h"
-
#include "slang-archive-file-system.h"
+#include "slang-basic.h"
namespace Slang
{
struct ZipFileSystem
{
- /// Create an empty zip
+ /// Create an empty zip
static SlangResult create(ComPtr<ISlangMutableFileSystem>& out);
- /// True if this appears to be a zip archive
+ /// True if this appears to be a zip archive
static bool isArchive(const void* data, size_t size);
};
-}
+} // namespace Slang
#endif
diff --git a/source/core/unix/slang-unix-process.cpp b/source/core/unix/slang-unix-process.cpp
index ee5484fd8..97b59f21c 100644
--- a/source/core/unix/slang-unix-process.cpp
+++ b/source/core/unix/slang-unix-process.cpp
@@ -1,50 +1,49 @@
// slang-unix-process.cpp
-#include "../slang-process.h"
-
#include "../slang-common.h"
-#include "../slang-string-util.h"
-#include "../slang-string-escape-util.h"
#include "../slang-memory-arena.h"
+#include "../slang-process.h"
+#include "../slang-string-escape-util.h"
+#include "../slang-string-util.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-//#include <dirent.h>
+// #include <dirent.h>
#include <errno.h>
-#include <poll.h>
#include <fcntl.h>
-
+#include <poll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#if SLANG_OSX
-# include <signal.h>
+#include <signal.h>
#endif
#include <time.h>
-namespace Slang {
+namespace Slang
+{
class UnixProcess : public Process
{
public:
- // Process
+ // Process
virtual bool isTerminated() SLANG_OVERRIDE;
virtual bool waitForTermination(Int timeInMs) SLANG_OVERRIDE;
virtual void terminate(int32_t returnValue) SLANG_OVERRIDE;
virtual void kill(int32_t returnValue) SLANG_OVERRIDE;
- UnixProcess(pid_t pid, Stream*const* streams);
+ UnixProcess(pid_t pid, Stream* const* streams);
protected:
- /// Returns true if terminated
+ /// Returns true if terminated
bool _updateTerminationState(int options);
- bool m_isTerminated = false; ///< True if ths process is terminated
- pid_t m_pid; ///< The process id
+ bool m_isTerminated = false; ///< True if ths process is terminated
+ pid_t m_pid; ///< The process id
};
class UnixPipeStream : public Stream
@@ -54,7 +53,12 @@ public:
// Stream
virtual Int64 getPosition() SLANG_OVERRIDE { return 0; }
- virtual SlangResult seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE { SLANG_UNUSED(origin); SLANG_UNUSED(offset); return SLANG_E_NOT_AVAILABLE; }
+ virtual SlangResult seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE
+ {
+ SLANG_UNUSED(origin);
+ SLANG_UNUSED(offset);
+ return SLANG_E_NOT_AVAILABLE;
+ }
virtual SlangResult read(void* buffer, size_t length, size_t& outReadBytes) SLANG_OVERRIDE;
virtual SlangResult write(const void* buffer, size_t length) SLANG_OVERRIDE;
virtual bool isEnd() SLANG_OVERRIDE { return m_isClosed; }
@@ -63,18 +67,15 @@ public:
virtual void close() SLANG_OVERRIDE;
virtual SlangResult flush() SLANG_OVERRIDE;
- UnixPipeStream(int fd, FileAccess access, bool isOwned) :
- m_fd(fd),
- m_access(access),
- m_isOwned(isOwned),
- m_isClosed(false)
+ UnixPipeStream(int fd, FileAccess access, bool isOwned)
+ : m_fd(fd), m_access(access), m_isOwned(isOwned), m_isClosed(false)
{
}
protected:
- /// This read file descriptor non blocking. Doing so will change the behavior of
- /// read - it can fail and return an error indicating there is no data, instead of blocking.
- /// Currently this mechanism isn't used, as checking via poll seemed to work.
+ /// This read file descriptor non blocking. Doing so will change the behavior of
+ /// read - it can fail and return an error indicating there is no data, instead of blocking.
+ /// Currently this mechanism isn't used, as checking via poll seemed to work.
void _setReadNonBlocking()
{
// Makes non blocking
@@ -86,16 +87,16 @@ protected:
}
bool _has(FileAccess access) const { return (Index(access) & Index(m_access)) != 0; }
- bool m_isClosed; ///< If true this stream has been closed (ie cannot read/write to anymore)
- bool m_isOwned; ///< True if m_fd is owned by this object.
- FileAccess m_access; ///< Access allowed to this stream - either Read or Write
- int m_fd; /// The 'file descriptor' for the pipe
+ bool m_isClosed; ///< If true this stream has been closed (ie cannot read/write to anymore)
+ bool m_isOwned; ///< True if m_fd is owned by this object.
+ FileAccess m_access; ///< Access allowed to this stream - either Read or Write
+ int m_fd; /// The 'file descriptor' for the pipe
};
/* !!!!!!!!!!!!!!!!!!!!!! UnixProcess !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-UnixProcess::UnixProcess(pid_t pid, Stream* const* streams):
- m_pid(pid)
+UnixProcess::UnixProcess(pid_t pid, Stream* const* streams)
+ : m_pid(pid)
{
// Set to an 'odd value'
m_returnValue = -1;
@@ -145,15 +146,16 @@ bool UnixProcess::waitForTermination(Int timeInMs)
// If < 0 we will wait blocking until terminated
if (timeInMs < 0)
{
- while (!_updateTerminationState(0));
+ while (!_updateTerminationState(0))
+ ;
return true;
}
- // Note that the amount of time waiting is very approximate (we are relying on sleeps time and don't take into
- // account time outside of sleeping)
+ // Note that the amount of time waiting is very approximate (we are relying on sleeps time and
+ // don't take into account time outside of sleeping)
// How often to test
- const Int checkRateMs = 100; /// Check every 0.1 seconds
+ const Int checkRateMs = 100; /// Check every 0.1 seconds
while (timeInMs > 0)
{
@@ -283,7 +285,7 @@ SlangResult UnixPipeStream::read(void* buffer, size_t length, size_t& outReadByt
{
return SLANG_OK;
}
- // Okay - guess we have an error then
+ // Okay - guess we have an error then
return SLANG_FAIL;
}
@@ -291,7 +293,7 @@ SlangResult UnixPipeStream::read(void* buffer, size_t length, size_t& outReadByt
// If no bytes were wanted, then there could still be bytes in the pipe
// before a HUP. So don't fall through to check for HUP.
- //
+ //
// If some bytes *were* wanted and none were read, we can allow fall through to
// handle HUP.
if (length == 0 || count > 0)
@@ -355,7 +357,7 @@ SlangResult UnixPipeStream::write(const void* buffer, size_t length)
/* !!!!!!!!!!!!!!!!!!!!!! Process !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-/* static */UnownedStringSlice Process::getExecutableSuffix()
+/* static */ UnownedStringSlice Process::getExecutableSuffix()
{
#if __CYGWIN__
return UnownedStringSlice::fromLiteral(".exe");
@@ -364,7 +366,7 @@ SlangResult UnixPipeStream::write(const void* buffer, size_t length)
#endif
}
-/* static */StringEscapeHandler* Process::getEscapeHandler()
+/* static */ StringEscapeHandler* Process::getEscapeHandler()
{
return StringEscapeUtil::getHandler(StringEscapeUtil::Style::Space);
}
@@ -377,9 +379,8 @@ static int pipeCLOEXEC(int pipefd[2])
// without pipe2 on macOS, there's an unavoidable race here where
// another process could fork and execv with execWatchPipe before we
// can set CLOEXEC on it...
- if(pipe(pipefd) == -1 ||
- fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1 ||
- fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) == -1)
+ if (pipe(pipefd) == -1 || fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1 ||
+ fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) == -1)
{
return -1;
}
@@ -389,7 +390,10 @@ static int pipeCLOEXEC(int pipefd[2])
#endif
}
-/* static */SlangResult Process::create(const CommandLine& commandLine, Process::Flags, RefPtr<Process>& outProcess)
+/* static */ SlangResult Process::create(
+ const CommandLine& commandLine,
+ Process::Flags,
+ RefPtr<Process>& outProcess)
{
const char* whatFailed = nullptr;
pid_t childPid;
@@ -404,7 +408,7 @@ static int pipeCLOEXEC(int pipefd[2])
// Add the command
argPtrs.add(exe.m_pathOrName.getBuffer());
- // Add all the args - they don't need any explicit escaping
+ // Add all the args - they don't need any explicit escaping
for (auto arg : commandLine.m_args)
{
// All args for this target must be unescaped (as they are in CommandLine)
@@ -425,9 +429,7 @@ static int pipeCLOEXEC(int pipefd[2])
// automatically if the child's exec succeeds
int execWatchPipe[2] = {-1, -1};
- if (pipe(stdinPipe) == -1 ||
- pipe(stdoutPipe) == -1 ||
- pipe(stderrPipe) == -1 ||
+ if (pipe(stdinPipe) == -1 || pipe(stdoutPipe) == -1 || pipe(stderrPipe) == -1 ||
pipeCLOEXEC(execWatchPipe) == -1)
{
whatFailed = "pipe";
@@ -438,36 +440,36 @@ static int pipeCLOEXEC(int pipefd[2])
// 0,1,2 in the child.
whatFailed = "fcntl";
int next;
- if(stdinPipe[0] < 3)
+ if (stdinPipe[0] < 3)
{
- if(-1 == (next = fcntl(stdinPipe[0], F_DUPFD, 3)))
+ if (-1 == (next = fcntl(stdinPipe[0], F_DUPFD, 3)))
{
goto reportErr;
}
close(stdinPipe[0]);
stdinPipe[0] = next;
}
- if(stdoutPipe[1] < 3)
+ if (stdoutPipe[1] < 3)
{
- if(-1 == (next = fcntl(stdoutPipe[1], F_DUPFD, 3)))
+ if (-1 == (next = fcntl(stdoutPipe[1], F_DUPFD, 3)))
{
goto reportErr;
}
close(stdoutPipe[1]);
stdoutPipe[1] = next;
}
- if(stderrPipe[1] < 3)
+ if (stderrPipe[1] < 3)
{
- if(-1 == (next = fcntl(stderrPipe[1], F_DUPFD, 3)))
+ if (-1 == (next = fcntl(stderrPipe[1], F_DUPFD, 3)))
{
goto reportErr;
}
close(stderrPipe[1]);
stderrPipe[1] = next;
}
- if(execWatchPipe[1] < 3)
+ if (execWatchPipe[1] < 3)
{
- if(-1 == (next = fcntl(execWatchPipe[1], F_DUPFD_CLOEXEC, 3)))
+ if (-1 == (next = fcntl(execWatchPipe[1], F_DUPFD_CLOEXEC, 3)))
{
goto reportErr;
}
@@ -516,14 +518,14 @@ static int pipeCLOEXEC(int pipefd[2])
// Signal the failure to our parent
int execErr = errno;
- if(::write(execWatchPipe[1], &execErr, sizeof(execErr)))
+ if (::write(execWatchPipe[1], &execErr, sizeof(execErr)))
fprintf(stderr, "error: `exec` watch pipe write failed\n");
// NOTE! Because we have dup2 into STDERR_FILENO, this error will *not* generally appear on
- // the terminal but in the stderrPipe.
+ // the terminal but in the stderrPipe.
fprintf(stderr, "error: `exec` failed\n");
- // Terminate with failure.
+ // Terminate with failure.
// Call _exit() rather than exit() so we don't run anything registered with atexit()
::_exit(kCannotExecute);
}
@@ -538,11 +540,14 @@ static int pipeCLOEXEC(int pipefd[2])
RefPtr<Stream> streams[Index(StdStreamType::CountOf)];
// Previously code didn't need to close, so we'll make stream now own the handles
- streams[Index(StdStreamType::Out)] = new UnixPipeStream(stdoutPipe[0], FileAccess::Read, true);
+ streams[Index(StdStreamType::Out)] =
+ new UnixPipeStream(stdoutPipe[0], FileAccess::Read, true);
stdoutPipe[0] = -1;
- streams[Index(StdStreamType::ErrorOut)] = new UnixPipeStream(stderrPipe[0], FileAccess::Read, true);
+ streams[Index(StdStreamType::ErrorOut)] =
+ new UnixPipeStream(stderrPipe[0], FileAccess::Read, true);
stderrPipe[0] = -1;
- streams[Index(StdStreamType::In)] = new UnixPipeStream(stdinPipe[1], FileAccess::Write, true);
+ streams[Index(StdStreamType::In)] =
+ new UnixPipeStream(stdinPipe[1], FileAccess::Write, true);
stdinPipe[1] = -1;
// Check that the exec actually succeeded
@@ -550,7 +555,7 @@ static int pipeCLOEXEC(int pipefd[2])
// Our success is if we read zero bytes, indicating that the pipe was
// closed by the child's exec and O_CLOEXEC. (and us just above)
const int readRes = ::read(execWatchPipe[0], &execErrCode, sizeof(execErrCode));
- if(readRes < 0)
+ if (readRes < 0)
{
whatFailed = "read from forked process";
goto reportErr;
@@ -563,11 +568,14 @@ static int pipeCLOEXEC(int pipefd[2])
const bool verbose = false;
if (verbose)
{
- fprintf(stderr, "error: exec for \"%s\" failed: %s\n", argPtrs[0],
- ::strerror(execErrCode));
+ fprintf(
+ stderr,
+ "error: exec for \"%s\" failed: %s\n",
+ argPtrs[0],
+ ::strerror(execErrCode));
}
whatFailed = "exec";
- // Don't report the exec as we expect some of them to fail
+ // Don't report the exec as we expect some of them to fail
goto closePipes;
}
@@ -592,19 +600,19 @@ closePipes:
return whatFailed ? SLANG_FAIL : SLANG_OK;
}
-/* static */uint64_t Process::getClockFrequency()
+/* static */ uint64_t Process::getClockFrequency()
{
return 1000000000;
}
-/* static */uint64_t Process::getClockTick()
+/* static */ uint64_t Process::getClockTick()
{
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return uint64_t(now.tv_sec) * 1000000000 + now.tv_nsec;
}
-/* static */void Process::sleepCurrentThread(Int timeInMs)
+/* static */ void Process::sleepCurrentThread(Int timeInMs)
{
struct timespec timeSpec;
@@ -626,26 +634,26 @@ closePipes:
nanosleep(&timeSpec, nullptr);
}
-/* static */SlangResult Process::getStdStream(StdStreamType type, RefPtr<Stream>& out)
+/* static */ SlangResult Process::getStdStream(StdStreamType type, RefPtr<Stream>& out)
{
switch (type)
{
- case StdStreamType::In:
+ case StdStreamType::In:
{
out = new UnixPipeStream(STDIN_FILENO, FileAccess::Read, false);
break;
}
- case StdStreamType::Out:
+ case StdStreamType::Out:
{
out = new UnixPipeStream(STDOUT_FILENO, FileAccess::Write, false);
- break;
+ break;
}
- case StdStreamType::ErrorOut:
+ case StdStreamType::ErrorOut:
{
out = new UnixPipeStream(STDERR_FILENO, FileAccess::Write, false);
break;
}
- default: return SLANG_FAIL;
+ default: return SLANG_FAIL;
}
return SLANG_OK;
}
diff --git a/source/core/windows/slang-win-process.cpp b/source/core/windows/slang-win-process.cpp
index 3aa21deb5..8569a0854 100644
--- a/source/core/windows/slang-win-process.cpp
+++ b/source/core/windows/slang-win-process.cpp
@@ -1,45 +1,64 @@
// slang-win-process-util.cpp
+#include "../slang-process-util.h"
#include "../slang-process.h"
-
-#include "../slang-string.h"
#include "../slang-string-escape-util.h"
#include "../slang-string-util.h"
-#include "../slang-process-util.h"
-
+#include "../slang-string.h"
#include "slang-com-helper.h"
#ifdef _WIN32
// TODO: We could try to avoid including this at all, but it would
// mean trying to hide certain struct layouts, which would add
// more dynamic allocation.
-# include <windows.h>
+#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifndef SLANG_RETURN_FAIL_ON_FALSE
-# define SLANG_RETURN_FAIL_ON_FALSE(x) if (!(x)) return SLANG_FAIL;
+#define SLANG_RETURN_FAIL_ON_FALSE(x) \
+ if (!(x)) \
+ return SLANG_FAIL;
#endif
-namespace Slang {
+namespace Slang
+{
// Has behavior very similar to unique_ptr - assignment is a move.
class WinHandle
{
public:
- /// Detach the encapsulated handle. Returns the handle (which now must be externally handled)
- HANDLE detach() { HANDLE handle = m_handle; m_handle = nullptr; return handle; }
+ /// Detach the encapsulated handle. Returns the handle (which now must be externally handled)
+ HANDLE detach()
+ {
+ HANDLE handle = m_handle;
+ m_handle = nullptr;
+ return handle;
+ }
/// Return as a handle
operator HANDLE() const { return m_handle; }
/// Assign
- void operator=(HANDLE handle) { setNull(); m_handle = handle; }
- void operator=(WinHandle&& rhs) { HANDLE handle = m_handle; m_handle = rhs.m_handle; rhs.m_handle = handle; }
+ void operator=(HANDLE handle)
+ {
+ setNull();
+ m_handle = handle;
+ }
+ void operator=(WinHandle&& rhs)
+ {
+ HANDLE handle = m_handle;
+ m_handle = rhs.m_handle;
+ rhs.m_handle = handle;
+ }
- /// Get ready for writing
- SLANG_FORCE_INLINE HANDLE* writeRef() { setNull(); return &m_handle; }
+ /// Get ready for writing
+ SLANG_FORCE_INLINE HANDLE* writeRef()
+ {
+ setNull();
+ return &m_handle;
+ }
/// Get for read access
SLANG_FORCE_INLINE const HANDLE* readRef() const { return &m_handle; }
@@ -54,21 +73,28 @@ public:
bool isNull() const { return m_handle == nullptr; }
/// Ctor
- WinHandle(HANDLE handle = nullptr) :m_handle(handle) {}
- WinHandle(WinHandle&& rhs) :m_handle(rhs.m_handle) { rhs.m_handle = nullptr; }
+ WinHandle(HANDLE handle = nullptr)
+ : m_handle(handle)
+ {
+ }
+ WinHandle(WinHandle&& rhs)
+ : m_handle(rhs.m_handle)
+ {
+ rhs.m_handle = nullptr;
+ }
/// Dtor
~WinHandle() { setNull(); }
private:
-
WinHandle(const WinHandle&) = delete;
void operator=(const WinHandle& rhs) = delete;
HANDLE m_handle;
};
-/* A simple Stream implementation of a File HANDLE (or Pipe). Note that currently does not allow getPosition/seek/atEnd */
+/* A simple Stream implementation of a File HANDLE (or Pipe). Note that currently does not allow
+ * getPosition/seek/atEnd */
class WinPipeStream : public Stream
{
public:
@@ -76,12 +102,23 @@ public:
// Stream
virtual Int64 getPosition() SLANG_OVERRIDE { return 0; }
- virtual SlangResult seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE { SLANG_UNUSED(origin); SLANG_UNUSED(offset); return SLANG_E_NOT_AVAILABLE; }
+ virtual SlangResult seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE
+ {
+ SLANG_UNUSED(origin);
+ SLANG_UNUSED(offset);
+ return SLANG_E_NOT_AVAILABLE;
+ }
virtual SlangResult read(void* buffer, size_t length, size_t& outReadBytes) SLANG_OVERRIDE;
virtual SlangResult write(const void* buffer, size_t length) SLANG_OVERRIDE;
virtual bool isEnd() SLANG_OVERRIDE { return m_streamHandle.isNull(); }
- virtual bool canRead() SLANG_OVERRIDE { return _has(FileAccess::Read) && !m_streamHandle.isNull(); }
- virtual bool canWrite() SLANG_OVERRIDE { return _has(FileAccess::Write) && !m_streamHandle.isNull(); }
+ virtual bool canRead() SLANG_OVERRIDE
+ {
+ return _has(FileAccess::Read) && !m_streamHandle.isNull();
+ }
+ virtual bool canWrite() SLANG_OVERRIDE
+ {
+ return _has(FileAccess::Write) && !m_streamHandle.isNull();
+ }
virtual void close() SLANG_OVERRIDE;
virtual SlangResult flush() SLANG_OVERRIDE;
@@ -90,7 +127,6 @@ public:
~WinPipeStream() { close(); }
protected:
-
bool _has(FileAccess access) const { return (Index(access) & Index(m_access)) != 0; }
SlangResult _updateState(BOOL res);
@@ -104,15 +140,14 @@ protected:
class WinProcess : public Process
{
public:
-
// Process
virtual bool isTerminated() SLANG_OVERRIDE;
virtual bool waitForTermination(Int timeInMs) SLANG_OVERRIDE;
virtual void terminate(int32_t returnCode) SLANG_OVERRIDE;
virtual void kill(int32_t returnCode) SLANG_OVERRIDE;
- WinProcess(HANDLE handle, Stream* const* streams) :
- m_processHandle(handle)
+ WinProcess(HANDLE handle, Stream* const* streams)
+ : m_processHandle(handle)
{
for (Index i = 0; i < Index(StdStreamType::CountOf); ++i)
{
@@ -121,17 +156,14 @@ public:
}
protected:
-
void _hasTerminated();
- WinHandle m_processHandle; ///< If not set the process has terminated
+ WinHandle m_processHandle; ///< If not set the process has terminated
};
/* !!!!!!!!!!!!!!!!!!!!!!!!!!! WinPipeStream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-WinPipeStream::WinPipeStream(HANDLE handle, FileAccess access, bool isOwned) :
- m_streamHandle(handle),
- m_access(access),
- m_isOwned(isOwned)
+WinPipeStream::WinPipeStream(HANDLE handle, FileAccess access, bool isOwned)
+ : m_streamHandle(handle), m_access(access), m_isOwned(isOwned)
{
// On Win32 a HANDLE has to be handled differently if it's a PIPE or FILE, so first determine
@@ -198,7 +230,13 @@ SlangResult WinPipeStream::read(void* buffer, size_t length, size_t& outReadByte
// Works on anonymous pipes too
// https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-peeknamedpipe
- SLANG_RETURN_ON_FAIL(_updateState(::PeekNamedPipe(m_streamHandle, nullptr, DWORD(0), &pipeBytesRead, &pipeTotalBytesAvailable, &pipeRemainingBytes)));
+ SLANG_RETURN_ON_FAIL(_updateState(::PeekNamedPipe(
+ m_streamHandle,
+ nullptr,
+ DWORD(0),
+ &pipeBytesRead,
+ &pipeTotalBytesAvailable,
+ &pipeRemainingBytes)));
// If there is nothing to read we are done
// If we don't do this ReadFile will *block* if there is nothing available
if (pipeTotalBytesAvailable == 0)
@@ -206,11 +244,13 @@ SlangResult WinPipeStream::read(void* buffer, size_t length, size_t& outReadByte
return SLANG_OK;
}
- SLANG_RETURN_ON_FAIL(_updateState(::ReadFile(m_streamHandle, buffer, DWORD(length), &bytesRead, nullptr)));
+ SLANG_RETURN_ON_FAIL(
+ _updateState(::ReadFile(m_streamHandle, buffer, DWORD(length), &bytesRead, nullptr)));
}
else
{
- SLANG_RETURN_ON_FAIL(_updateState(::ReadFile(m_streamHandle, buffer, DWORD(length), &bytesRead, nullptr)));
+ SLANG_RETURN_ON_FAIL(
+ _updateState(::ReadFile(m_streamHandle, buffer, DWORD(length), &bytesRead, nullptr)));
// If it's not a pipe, and there is nothing left, then we are done.
if (length > 0 && bytesRead == 0)
@@ -248,7 +288,7 @@ SlangResult WinPipeStream::write(const void* buffer, size_t length)
close();
return SLANG_FAIL;
}
-
+
SLANG_UNUSED(err);
return SLANG_FAIL;
}
@@ -265,7 +305,7 @@ void WinPipeStream::close()
{
if (!m_isOwned)
{
- // If we don't own it just detach it
+ // If we don't own it just detach it
m_streamHandle.detach();
}
m_streamHandle.setNull();
@@ -357,31 +397,31 @@ void WinProcess::kill(int32_t returnCode)
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-/* static */StringEscapeHandler* Process::getEscapeHandler()
+/* static */ StringEscapeHandler* Process::getEscapeHandler()
{
return StringEscapeUtil::getHandler(StringEscapeUtil::Style::Space);
}
-/* static */UnownedStringSlice Process::getExecutableSuffix()
+/* static */ UnownedStringSlice Process::getExecutableSuffix()
{
return UnownedStringSlice::fromLiteral(".exe");
}
-/* static */SlangResult Process::getStdStream(StdStreamType type, RefPtr<Stream>& out)
+/* static */ SlangResult Process::getStdStream(StdStreamType type, RefPtr<Stream>& out)
{
switch (type)
{
- case StdStreamType::In:
+ case StdStreamType::In:
{
out = new WinPipeStream(GetStdHandle(STD_INPUT_HANDLE), FileAccess::Read, false);
return SLANG_OK;
}
- case StdStreamType::Out:
+ case StdStreamType::Out:
{
out = new WinPipeStream(GetStdHandle(STD_OUTPUT_HANDLE), FileAccess::Write, false);
return SLANG_OK;
}
- case StdStreamType::ErrorOut:
+ case StdStreamType::ErrorOut:
{
out = new WinPipeStream(GetStdHandle(STD_ERROR_HANDLE), FileAccess::Write, false);
return SLANG_OK;
@@ -391,10 +431,13 @@ void WinProcess::kill(int32_t returnCode)
return SLANG_FAIL;
}
-/* static */SlangResult Process::create(const CommandLine& commandLine, Process::Flags flags, RefPtr<Process>& outProcess)
-{
+/* static */ SlangResult Process::create(
+ const CommandLine& commandLine,
+ Process::Flags flags,
+ RefPtr<Process>& outProcess)
+{
WinHandle childStdOutRead;
- WinHandle childStdErrRead;
+ WinHandle childStdErrRead;
WinHandle childStdInWrite;
WinHandle processHandle;
@@ -409,7 +452,7 @@ void WinProcess::kill(int32_t returnCode)
securityAttributes.bInheritHandle = true;
// 0 means use the 'system default'
- //const DWORD bufferSize = 64 * 1024;
+ // const DWORD bufferSize = 64 * 1024;
const DWORD bufferSize = 0;
{
@@ -417,26 +460,59 @@ void WinProcess::kill(int32_t returnCode)
WinHandle childStdErrReadTmp;
WinHandle childStdInWriteTmp;
// create stdout pipe for child process
- SLANG_RETURN_FAIL_ON_FALSE(CreatePipe(childStdOutReadTmp.writeRef(), childStdOutWrite.writeRef(), &securityAttributes, bufferSize));
+ SLANG_RETURN_FAIL_ON_FALSE(CreatePipe(
+ childStdOutReadTmp.writeRef(),
+ childStdOutWrite.writeRef(),
+ &securityAttributes,
+ bufferSize));
if ((flags & Process::Flag::DisableStdErrRedirection) == 0)
{
// create stderr pipe for child process
- SLANG_RETURN_FAIL_ON_FALSE(CreatePipe(childStdErrReadTmp.writeRef(), childStdErrWrite.writeRef(), &securityAttributes, bufferSize));
+ SLANG_RETURN_FAIL_ON_FALSE(CreatePipe(
+ childStdErrReadTmp.writeRef(),
+ childStdErrWrite.writeRef(),
+ &securityAttributes,
+ bufferSize));
}
- // create stdin pipe for child process
- SLANG_RETURN_FAIL_ON_FALSE(CreatePipe(childStdInRead.writeRef(), childStdInWriteTmp.writeRef(), &securityAttributes, bufferSize));
+ // create stdin pipe for child process
+ SLANG_RETURN_FAIL_ON_FALSE(CreatePipe(
+ childStdInRead.writeRef(),
+ childStdInWriteTmp.writeRef(),
+ &securityAttributes,
+ bufferSize));
const HANDLE currentProcess = GetCurrentProcess();
// https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-duplicatehandle
- // create a non-inheritable duplicate of the stdout reader
- SLANG_RETURN_FAIL_ON_FALSE(DuplicateHandle(currentProcess, childStdOutReadTmp, currentProcess, childStdOutRead.writeRef(), 0, FALSE, DUPLICATE_SAME_ACCESS));
+ // create a non-inheritable duplicate of the stdout reader
+ SLANG_RETURN_FAIL_ON_FALSE(DuplicateHandle(
+ currentProcess,
+ childStdOutReadTmp,
+ currentProcess,
+ childStdOutRead.writeRef(),
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS));
// create a non-inheritable duplicate of the stderr reader
if (childStdErrReadTmp)
- SLANG_RETURN_FAIL_ON_FALSE(DuplicateHandle(currentProcess, childStdErrReadTmp, currentProcess, childStdErrRead.writeRef(), 0, FALSE, DUPLICATE_SAME_ACCESS));
+ SLANG_RETURN_FAIL_ON_FALSE(DuplicateHandle(
+ currentProcess,
+ childStdErrReadTmp,
+ currentProcess,
+ childStdErrRead.writeRef(),
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS));
// create a non-inheritable duplicate of the stdin writer
- SLANG_RETURN_FAIL_ON_FALSE(DuplicateHandle(currentProcess, childStdInWriteTmp, currentProcess, childStdInWrite.writeRef(), 0, FALSE, DUPLICATE_SAME_ACCESS));
+ SLANG_RETURN_FAIL_ON_FALSE(DuplicateHandle(
+ currentProcess,
+ childStdInWriteTmp,
+ currentProcess,
+ childStdInWrite.writeRef(),
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS));
}
// TODO: switch to proper wide-character versions of these...
@@ -478,12 +554,14 @@ void WinProcess::kill(int32_t returnCode)
}
// From docs:
- // If both lpApplicationName and lpCommandLine are non-NULL, the null-terminated string pointed to by lpApplicationName
- // specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line.
+ // If both lpApplicationName and lpCommandLine are non-NULL, the null-terminated string
+ // pointed to by lpApplicationName specifies the module to execute, and the null-terminated
+ // string pointed to by lpCommandLine specifies the command line.
// JS:
- // Somewhat confusingly this means that even if lpApplicationName is specified, it muse *ALSO* be included as the first
- // whitespace delimited arg must *also* be the (possibly) quoted executable
+ // Somewhat confusingly this means that even if lpApplicationName is specified, it muse
+ // *ALSO* be included as the first whitespace delimited arg must *also* be the (possibly)
+ // quoted executable
// https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessa
// `CreateProcess` requires write access to this, for some reason...
@@ -510,9 +588,9 @@ void WinProcess::kill(int32_t returnCode)
{
// Lets see if we can set up to debug
// https://docs.microsoft.com/en-us/windows/win32/debug/debugging-a-running-process
-
- //DebugActiveProcess(processInfo.dwProcessId);
-
+
+ // DebugActiveProcess(processInfo.dwProcessId);
+
// Resume the thread
ResumeThread(processInfo.hThread);
}
@@ -527,15 +605,18 @@ void WinProcess::kill(int32_t returnCode)
RefPtr<Stream> streams[Index(StdStreamType::CountOf)];
if (childStdErrRead)
- streams[Index(StdStreamType::ErrorOut)] = new WinPipeStream(childStdErrRead.detach(), FileAccess::Read);
- streams[Index(StdStreamType::Out)] = new WinPipeStream(childStdOutRead.detach(), FileAccess::Read);
- streams[Index(StdStreamType::In)] = new WinPipeStream(childStdInWrite.detach(), FileAccess::Write);
+ streams[Index(StdStreamType::ErrorOut)] =
+ new WinPipeStream(childStdErrRead.detach(), FileAccess::Read);
+ streams[Index(StdStreamType::Out)] =
+ new WinPipeStream(childStdOutRead.detach(), FileAccess::Read);
+ streams[Index(StdStreamType::In)] =
+ new WinPipeStream(childStdInWrite.detach(), FileAccess::Write);
outProcess = new WinProcess(processHandle.detach(), streams[0].readRef());
return SLANG_OK;
}
-/* static */void Process::sleepCurrentThread(Int timeInMs)
+/* static */ void Process::sleepCurrentThread(Int timeInMs)
{
::Sleep(DWORD(timeInMs));
}
@@ -549,12 +630,12 @@ static uint64_t _getClockFrequency()
static const uint64_t g_frequency = _getClockFrequency();
-/* static */uint64_t Process::getClockFrequency()
+/* static */ uint64_t Process::getClockFrequency()
{
return g_frequency;
}
-/* static */uint64_t Process::getClockTick()
+/* static */ uint64_t Process::getClockTick()
{
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);