diff options
Diffstat (limited to 'source/compiler-core/slang-artifact-util.cpp')
| -rw-r--r-- | source/compiler-core/slang-artifact-util.cpp | 90 |
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 |
