slang-blob.cpp
#include "slang-blob.h"
namespace Slang {
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BlobBase !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
ISlangUnknown* BlobBase::getInterface(const Guid& guid)
{
if (guid == ISlangUnknown::getTypeGuid() ||
guid == ISlangBlob::getTypeGuid())
{
return static_cast<ISlangBlob*>(this);
}
if (guid == ICastable::getTypeGuid())
{
return static_cast<ICastable*>(this);
}
return nullptr;
}
void* BlobBase::getObject(const Guid& guid)
{
SLANG_UNUSED(guid);
return nullptr;
}
void* BlobBase::castAs(const SlangUUID& guid)
{
if (auto intf = getInterface(guid))
{
return intf;
}
return getObject(guid);
}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
StringBlob::StringBlob(MoveUnique, String& in)
{
auto rep = in.getStringRepresentation();
if (rep && !rep->isUniquelyReferenced())
{
// Make a new unique copy
m_string = in.getUnownedSlice();
// Move out of in
String tmp;
tmp.swapWith(in);
}
else
{
// Must either not have a rep or be unique
m_string.swapWith(in);
}
}
void* StringBlob::castAs(const SlangUUID& guid)
{
if (auto intf = getInterface(guid))
{
return intf;
}
return getObject(guid);
}
void* StringBlob::getObject(const Guid& guid)
{
// Can allow accessing the contained String
if (guid == getTypeGuid())
{
return this;
}
// Can always be accessed as terminated char*
if (guid == SlangTerminatedChars::getTypeGuid())
{
return const_cast<char*>(m_string.getBuffer());
}
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)
{
if (auto intf = getInterface(guid))
{
return intf;
}
return getObject(guid);
}
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 nullptr;
}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ScopeBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
void* ScopeBlob::castAs(const SlangUUID& guid)
{
if (auto intf = getInterface(guid))
{
return intf;
}
if (auto obj = getObject(guid))
{
return obj;
}
// If the contained thing is castable, ask it
if (m_castable)
{
return m_castable->castAs(guid);
}
return nullptr;
}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ListBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
void* ListBlob::castAs(const SlangUUID& guid)
{
if (auto intf = getInterface(guid))
{
return intf;
}
return getObject(guid);
}
void* ListBlob::getObject(const Guid& guid)
{
// If the data is terminated return the pointer
if (guid == SlangTerminatedChars::getTypeGuid())
{
const auto count = m_data.getCount();
if (m_data.getCapacity() > count)
{
auto buf = m_data.getBuffer();
if (buf[count] == 0)
{
return (char*)buf;
}
}
}
return nullptr;
}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StaticBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
SlangResult StaticBlob::queryInterface(SlangUUID const& guid, void** outObject)
{
if (auto intf = getInterface(guid))
{
*outObject = intf;
return SLANG_OK;
}
return SLANG_E_NO_INTERFACE;
}
void* StaticBlob::castAs(const SlangUUID& guid)
{
if (auto intf = getInterface(guid))
{
return intf;
}
return getObject(guid);
}
ISlangUnknown* StaticBlob::getInterface(const Guid& guid)
{
if (guid == ISlangUnknown::getTypeGuid() ||
guid == ISlangBlob::getTypeGuid())
{
return static_cast<ISlangBlob*>(this);
}
if (guid == ICastable::getTypeGuid())
{
return static_cast<ICastable*>(this);
}
return nullptr;
}
void* StaticBlob::getObject(const Guid& guid)
{
SLANG_UNUSED(guid);
return nullptr;
}
} // namespace Slang