1
2
3
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& cmajorRootDir, const std::string& filePath)
32 {
33 if (filePath.find(cmajorRootDir, 0) == 0)
34 {
35 return "$CMAJOR$" + filePath.substr(cmajorRootDir.size());
36 }
37 return filePath;
38 }
39
40 std::string MakeFullPathFromCmajorRootDirRelativeFilePath(const std::string& cmajorRootDir, const std::string& filePath)
41 {
42 if (filePath.find("$CMAJOR$") == 0)
43 {
44 return Path::Combine(cmajorRootDir, filePath.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& writer, const std::string& cmajorRootDir)
58 {
59 writer.Write(name);
60 writer.Write(static_cast<int32_t>(type));
61 writer.Write(MakeCmajorRootDirRelativeFilePath(cmajorRootDir, filePath));
62 }
63
64 void Resource::Read(BinaryReader& reader, const std::string& cmajorRootDir)
65 {
66 name = reader.ReadUtf32String();
67 type = static_cast<Type>(reader.ReadInt());
68 filePath = reader.ReadUtf8String();
69 filePath = MakeFullPathFromCmajorRootDirRelativeFilePath(cmajorRootDir, filePath);
70 }
71
72 void Resource::Dump(CodeFormatter& formatter, int 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(writer, cmajorRootDir);
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(reader, cmajorRootDir);
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(formatter, index);
135 ++index;
136 }
137 }
138
139 } }