1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <sngcm/ast/SystemFileIndex.hpp>
  7 #include <sngcm/ast/Project.hpp>
  8 #include <soulng/util/Path.hpp>
  9 #include <soulng/util/BinaryWriter.hpp>
 10 #include <soulng/util/BinaryReader.hpp>
 11 #include <mutex>
 12 
 13 namespace sngcm { namespace ast {
 14 
 15 using namespace soulng::util;
 16 
 17 std::unique_ptr<SystemFileIndex> SystemFileIndex::instance;
 18 
 19 void SystemFileIndex::Init()
 20 {
 21     instance.reset(new SystemFileIndex());
 22 }
 23 
 24 SystemFileIndex::SystemFileIndex() : nextSystemFileIndex(firstSystemFileIndex)cmajorRootDir(GetFullPath(CmajorRootDir()))
 25 {
 26 }
 27 
 28 std::mutex mtx;
 29 
 30 uint32_t SystemFileIndex::RegisterSystemSourceFile(const std::string& systemSourceFilePath)
 31 {
 32     std::lock_guard<std::mutex> lock(mtx);
 33     uint32_t fileIndex = nextSystemFileIndex++;
 34     std::string sfp = GetFullPath(systemSourceFilePath);
 35     if (sfp.find(cmajorRootDir0) == 0)
 36     {
 37         sfp = sfp.substr(cmajorRootDir.size());
 38     }
 39     else
 40     {
 41         throw std::runtime_error("CMAJOR_ROOT path prefix '" + cmajorRootDir + "' differs from prefix of system source file path '" + sfp + "'");
 42     }
 43     systemFileMap[fileIndex] = sfp;
 44     return fileIndex;
 45 }
 46 
 47 std::string SystemFileIndex::GetSystemSourceFilePath(uint32_t systemFileIndex) const
 48 {
 49     std::lock_guard<std::mutex> lock(mtx);
 50     auto it = systemFileMap.find(systemFileIndex);
 51     if (it != systemFileMap.cend())
 52     {
 53         std::string sourceFilePath = it->second;
 54         boost::filesystem::path p(cmajorRootDir);
 55         p /= sourceFilePath;
 56         std::string sfp = GetFullPath(p.generic_string());
 57         return sfp;
 58     }
 59     else
 60     {
 61         throw std::runtime_error("system file index contains no system source file path for index " + std::to_string(systemFileIndex));
 62     }
 63 }
 64 
 65 void SystemFileIndex::Write(const std::string& systemFileIndexFilePath)
 66 {
 67     std::lock_guard<std::mutex> lock(mtx);
 68     BinaryWriter writer(systemFileIndexFilePath);
 69     writer.Write(nextSystemFileIndex);
 70     uint32_t n = systemFileMap.size();
 71     writer.Write(n);
 72     for (const auto& p : systemFileMap)
 73     {
 74         uint32_t index = p.first;
 75         const std::string& sourceFilePath = p.second;
 76         writer.Write(index);
 77         writer.Write(sourceFilePath);
 78     }
 79 }
 80 
 81 void SystemFileIndex::Read(const std::string& systemFileIndexFilePath)
 82 {
 83     std::lock_guard<std::mutex> lock(mtx);
 84     nextSystemFileIndex = firstSystemFileIndex;
 85     systemFileMap.clear();
 86     BinaryReader reader(systemFileIndexFilePath);
 87     nextSystemFileIndex = reader.ReadUInt();
 88     uint32_t n = reader.ReadUInt();
 89     for (uint32_t i = 0; i < n; ++i)
 90     {
 91         uint32_t index = reader.ReadUInt();
 92         std::string sourceFilepath = reader.ReadUtf8String();
 93         systemFileMap[index] = sourceFilepath;
 94     }
 95 }
 96 
 97 void SystemFileIndexInit()
 98 {
 99     SystemFileIndex::Init();
100 }
101 
102 } } // namespace sngcm::ast