summaryrefslogtreecommitdiffstats
path: root/source/core/slang-blob.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-06-08 17:26:33 -0400
committerGitHub <noreply@github.com>2023-06-08 17:26:33 -0400
commit3913091a021a8f4525f0050dfb83d1c2b8fc6f6b (patch)
tree32d7560aa9ca037db8c156776b83785cac7994f0 /source/core/slang-blob.cpp
parentc492288b4778b19bd66ac31edb076add096e757d (diff)
Improvements around StringBlob (#2921)
* #include an absolute path didn't work - because paths were taken to always be relative. * Small fixes and improvements around reflection tool. * Make PrettyWriter printing a class. * Improvements around handling StringBlob and storing stdlib source in ISlangBlob. * Fix some issues with comments around StringBlob. * Default initialize StringBlob fields.
Diffstat (limited to 'source/core/slang-blob.cpp')
-rw-r--r--source/core/slang-blob.cpp122
1 files changed, 101 insertions, 21 deletions
diff --git a/source/core/slang-blob.cpp b/source/core/slang-blob.cpp
index a4acb98cb..c360f483b 100644
--- a/source/core/slang-blob.cpp
+++ b/source/core/slang-blob.cpp
@@ -35,25 +35,115 @@ void* BlobBase::castAs(const SlangUUID& guid)
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-StringBlob::StringBlob(MoveUnique, String& in)
+void StringBlob::_uniqueInit(StringRepresentation* uniqueRep)
{
- auto rep = in.getStringRepresentation();
- if (rep && !rep->isUniquelyReferenced())
+ // When initing the rep either has to be nullptr *or* uniquely referenced
+ // so we can take ownership of it.
+
+ SLANG_ASSERT(uniqueRep == nullptr || uniqueRep->isUniquelyReferenced());
+
+ m_rep = uniqueRep;
+
+ // If it's nullptr, that means the string is the empty string. To handle we
+ //
+ if (!uniqueRep)
+ {
+ m_chars = "";
+ m_charsCount = 0;
+ }
+ else
{
- // Make a new unique copy
- m_string = in.getUnownedSlice();
+ m_chars = uniqueRep->getData();
+ m_charsCount = uniqueRep->getLength();
+ }
+
+ _checkRep();
+}
- // Move out of in
- String tmp;
- tmp.swapWith(in);
+void StringBlob::_init(StringRepresentation* rep)
+{
+ if (rep)
+ {
+ // Even if the uniqueRep is 1, we can't assume we can take ownership
+ // So we make a copy
+
+ // If the length is 0, we can just init as empty
+ auto length = rep->getLength();
+ if (length == 0)
+ {
+ rep = nullptr;
+ }
+ else
+ {
+ const UnownedStringSlice slice(rep->getData(), length);
+ rep = StringRepresentation::createWithReference(slice);
+ }
+ }
+
+ // Must be unique at this point
+ _uniqueInit(rep);
+
+ _checkRep();
+}
+
+void StringBlob::_moveInit(StringRepresentation* rep)
+{
+ if (rep && !rep->isUniquelyReferenced())
+ {
+ // Will make a copy of the rep
+ _init(rep);
+ // We need to release a ref as rep is passed in with the 'current' ref count
+ rep->releaseReference();
}
else
{
- // Must either not have a rep or be unique
- m_string.swapWith(in);
+ _uniqueInit(rep);
+ }
+ _checkRep();
+}
+
+/* static */ComPtr<ISlangBlob> StringBlob::create(const UnownedStringSlice& slice)
+{
+ StringRepresentation* rep = nullptr;
+ if (slice.getLength())
+ {
+ rep = StringRepresentation::createWithReference(slice);
}
+
+ // rep must be unique at this point
+ auto blob = new StringBlob;
+ blob->_uniqueInit(rep);
+ return ComPtr<ISlangBlob>(blob);
+}
+
+/* static */ComPtr<ISlangBlob> StringBlob::create(const String& in)
+{
+ auto blob = new StringBlob;
+ blob->_init(in.getStringRepresentation());
+ return ComPtr<ISlangBlob>(blob);
}
+/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String& in)
+{
+ auto blob = new StringBlob;
+ blob->_moveInit(in.detachStringRepresentation());
+ return ComPtr<ISlangBlob>(blob);
+}
+
+/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String&& in)
+{
+ auto blob = new StringBlob;
+ blob->_moveInit(in.detachStringRepresentation());
+ return ComPtr<ISlangBlob>(blob);
+}
+
+StringBlob::~StringBlob()
+{
+ if (m_rep)
+ {
+ delete m_rep;
+ }
+}
void* StringBlob::castAs(const SlangUUID& guid)
{
if (auto intf = getInterface(guid))
@@ -73,21 +163,11 @@ void* StringBlob::getObject(const Guid& guid)
// Can always be accessed as terminated char*
if (guid == SlangTerminatedChars::getTypeGuid())
{
- return const_cast<char*>(m_string.getBuffer());
+ return const_cast<char*>(m_chars);
}
return nullptr;
}
-/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String& in)
-{
- return ComPtr<ISlangBlob>(new StringBlob(MoveUnique{}, in));
-}
-
-/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String&& in)
-{
- return ComPtr<ISlangBlob>(new StringBlob(MoveUnique{}, in));
-}
-
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RawBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
void* RawBlob::castAs(const SlangUUID& guid)