1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <cmajor/symbols/ResourceTable.hpp>
  7 #include <sngcm/ast/Project.hpp>
  8 #include <soulng/util/Path.hpp>
  9 #include <soulng/util/TextUtils.hpp>
 10 #include <soulng/util/Unicode.hpp>
 11 
 12 namespace cmajor { namespace symbols {
 13 
 14 using sngcm::ast::CmajorRootDir;
 15 using soulng::util::GetFullPath;
 16 using soulng::util::Path;
 17 using soulng::util::EndsWith;
 18 using soulng::unicode::ToUtf8;
 19 
 20 std::string ResourceTypeStr(Resource::Type resourceType)
 21 {
 22     switch (resourceType)
 23     {
 24         case Resource::Type::bitmap: return "bitmap";
 25         case Resource::Type::icon: return "icon";
 26         case Resource::Type::cursor: return "cursor";
 27     }
 28     return std::string();
 29 }
 30 
 31 std::string MakeCmajorRootDirRelativeFilePath(const std::string& cmajorRootDirconst std::string& filePath)
 32 {
 33     if (filePath.find(cmajorRootDir0) == 0)
 34     {
 35         return "$CMAJOR$" + filePath.substr(cmajorRootDir.size());
 36     }
 37     return filePath;
 38 }
 39 
 40 std::string MakeFullPathFromCmajorRootDirRelativeFilePath(const std::string& cmajorRootDirconst std::string& filePath)
 41 {
 42     if (filePath.find("$CMAJOR$") == 0)
 43     {
 44         return Path::Combine(cmajorRootDirfilePath.substr(8));
 45     }
 46     return filePath;
 47 }
 48 
 49 Resource::Resource() : name()type()filePath()
 50 {
 51 }
 52 
 53 Resource::Resource(const std::u32string& name_Type type_const std::string& filePath_) : name(name_)type(type_)filePath(GetFullPath(filePath_))
 54 {
 55 }
 56 
 57 void Resource::Write(BinaryWriter& writerconst std::string& cmajorRootDir)
 58 {
 59     writer.Write(name);
 60     writer.Write(static_cast<int32_t>(type));
 61     writer.Write(MakeCmajorRootDirRelativeFilePath(cmajorRootDirfilePath));
 62 }
 63 
 64 void Resource::Read(BinaryReader& readerconst std::string& cmajorRootDir)
 65 {
 66     name = reader.ReadUtf32String();
 67     type = static_cast<Type>(reader.ReadInt());
 68     filePath = reader.ReadUtf8String();
 69     filePath = MakeFullPathFromCmajorRootDirRelativeFilePath(cmajorRootDirfilePath);
 70 }
 71 
 72 void Resource::Dump(CodeFormatter& formatterint index)
 73 {
 74     formatter.WriteLine("RESOURCE " + std::to_string(index));
 75     formatter.WriteLine("resource name: " + ToUtf8(name));
 76     formatter.WriteLine("resource type: " + ResourceTypeStr(type));
 77     formatter.WriteLine("resource file: " + filePath);
 78 }
 79 
 80 bool ResourceTable::Contains(const std::u32string& resourceName) const
 81 {
 82     return resourceNameSet.find(resourceName) != resourceNameSet.cend();
 83 }
 84 
 85 void ResourceTable::AddResource(const Resource& resource)
 86 {
 87     resourceNameSet.insert(resource.name);
 88     resources.push_back(resource);
 89 }
 90 
 91 void ResourceTable::Write(BinaryWriter& writer)
 92 {
 93     int32_t n = resources.size();
 94     writer.Write(n);
 95     if (n > 0)
 96     {
 97         std::string cmajorRootDir = GetFullPath(CmajorRootDir());
 98         if (!EndsWith(cmajorRootDir"/"))
 99         {
100             cmajorRootDir.append("/");
101         }
102         for (int32_t i = 0; i < n; ++i)
103         {
104             resources[i].Write(writercmajorRootDir);
105         }
106     }
107 }
108 
109 void ResourceTable::Read(BinaryReader& reader)
110 {
111     int32_t n = reader.ReadInt();
112     if (n > 0)
113     {
114         std::string cmajorRootDir = GetFullPath(CmajorRootDir());
115         if (!EndsWith(cmajorRootDir"/"))
116         {
117             cmajorRootDir.append("/");
118         }
119         for (int32_t i = 0; i < n; ++i)
120         {
121             Resource resource;
122             resource.Read(readercmajorRootDir);
123             resources.push_back(resource);
124         }
125     }
126 }
127 
128 void ResourceTable::Dump(CodeFormatter& formatter)
129 {
130     formatter.WriteLine("RESOURCE TABLE:");
131     int index = 0;
132     for (Resource& resource : resources)
133     {
134         resource.Dump(formatterindex);
135         ++index;
136     }
137 }
138 
139 } } // namespace cmajor::symbols