summaryrefslogtreecommitdiffstats
path: root/source/compiler-core/slang-artifact-util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/compiler-core/slang-artifact-util.cpp')
-rw-r--r--source/compiler-core/slang-artifact-util.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp
index 3ca10446c..5c1641f7f 100644
--- a/source/compiler-core/slang-artifact-util.cpp
+++ b/source/compiler-core/slang-artifact-util.cpp
@@ -3,8 +3,13 @@
#include "slang-artifact-info.h"
+#include "../core/slang-file-system.h"
+#include "../core/slang-io.h"
+
namespace Slang {
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactUtilImpl !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
/* static */ArtifactUtilImpl ArtifactUtilImpl::g_singleton;
SlangResult ArtifactUtilImpl::queryInterface(SlangUUID const& uuid, void** outObject)
@@ -60,4 +65,89 @@ ArtifactStyle ArtifactUtilImpl::getStyleParent(ArtifactStyle style) { return get
UnownedStringSlice ArtifactUtilImpl::getStyleName(ArtifactStyle style) { return getName(style); }
bool ArtifactUtilImpl::isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) { return isDerivedFrom(style, base); }
+SlangResult ArtifactUtilImpl::createLockFile(const char* inNameBase, ISlangMutableFileSystem* fileSystem, ILockFile** outLockFile)
+{
+ if (fileSystem)
+ {
+ if (fileSystem != OSFileSystem::getMutableSingleton())
+ {
+ // We can only create lock files, on the global OS file system
+ return SLANG_E_NOT_AVAILABLE;
+ }
+ fileSystem = nullptr;
+ }
+
+ const UnownedStringSlice nameBase = (inNameBase && inNameBase[0] != 0) ? UnownedStringSlice(inNameBase) : UnownedStringSlice("unknown");
+
+ String lockPath;
+ SLANG_RETURN_ON_FAIL(File::generateTemporary(nameBase, lockPath));
+
+ ComPtr<ILockFile> lockFile(new LockFile(lockPath, fileSystem));
+
+ *outLockFile = lockFile.detach();
+ return SLANG_OK;
+}
+
+SlangResult ArtifactUtilImpl::calcArtifactPath(const ArtifactDesc& desc, const char* inBasePath, ISlangBlob** outPath)
+{
+ UnownedStringSlice basePath(inBasePath);
+
+ StringBuilder path;
+ SLANG_RETURN_ON_FAIL(ArtifactInfoUtil::calcPathForDesc(desc, basePath, path));
+
+ auto blob = new StringBlob(path);
+ blob->addRef();
+ *outPath = blob;
+ return SLANG_OK;
+}
+
+SlangResult ArtifactUtilImpl::requireFileDefaultImpl(IArtifact* artifact, ArtifactKeep keep, IFileArtifactRepresentation** outFile)
+{
+ // See if we already have it
+ if (auto fileRep = findItem<IFileArtifactRepresentation>(artifact))
+ {
+ fileRep->addRef();
+ *outFile = fileRep;
+ return SLANG_OK;
+ }
+
+ // If we are going to access as a file we need to be able to write it, and to do that we need a blob
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(keep, blob.writeRef()));
+
+ // Okay we need to store as a temporary. Get a lock file.
+ ComPtr<ILockFile> lockFile;
+ SLANG_RETURN_ON_FAIL(createLockFile(artifact->getName(), nullptr, lockFile.writeRef()));
+
+ // Now we need the appropriate name for this item
+ ComPtr<ISlangBlob> pathBlob;
+ SLANG_RETURN_ON_FAIL(calcArtifactPath(artifact->getDesc(), lockFile->getPath(), pathBlob.writeRef()));
+
+ const auto path = StringUtil::getString(pathBlob);
+
+ // Write the contents
+ SLANG_RETURN_ON_FAIL(File::writeAllBytes(path, blob->getBufferPointer(), blob->getBufferSize()));
+
+ // If the paths are identical we don't need a lock file
+ if (UnownedStringSlice(lockFile->getPath()) == path.getUnownedSlice())
+ {
+ // Make the lockFile no longer own the file
+ lockFile->disown();
+ // We no longer need the lock file
+ lockFile.setNull();
+ }
+
+ // Create the rep
+ IFileArtifactRepresentation* fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Owned, path, lockFile, nullptr);
+ if (canKeep(keep))
+ {
+ artifact->addItem(fileRep);
+ }
+
+ // Return it
+ fileRep->addRef();
+ *outFile = fileRep;
+ return SLANG_OK;
+}
+
} // namespace Slang