index_v1.cpp (5187B)
1 /* ReaPack: Package manager for REAPER 2 * Copyright (C) 2015-2025 Christian Fillion 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "index.hpp" 19 20 #include "errors.hpp" 21 #include "xml.hpp" 22 23 #include <sstream> 24 25 static void LoadMetadataV1(XmlNode, Metadata *); 26 static void LoadCategoryV1(XmlNode, Index *); 27 static void LoadPackageV1(XmlNode, Category *); 28 static void LoadVersionV1(XmlNode, Package *); 29 static void LoadSourceV1(XmlNode, Version *, bool hasArm64Ec); 30 31 void Index::loadV1(XmlNode root, Index *ri) 32 { 33 if(ri->name().empty()) { 34 if(const XmlString &name = root.attribute("name")) 35 ri->setName(*name); 36 } 37 38 for(XmlNode node = root.firstChild("category"); 39 node; node = node.nextSibling("category")) 40 LoadCategoryV1(node, ri); 41 42 if(XmlNode node = root.firstChild("metadata")) 43 LoadMetadataV1(node, ri->metadata()); 44 } 45 46 void LoadMetadataV1(XmlNode meta, Metadata *md) 47 { 48 XmlNode node = meta.firstChild("description"); 49 50 if(node) { 51 if(const XmlString &rtf = node.text()) 52 md->setAbout(*rtf); 53 } 54 55 node = meta.firstChild("link"); 56 57 for(node = meta.firstChild("link"); node; node = node.nextSibling("link")) { 58 const XmlString &rel = node.attribute("rel"), 59 &url = node.attribute("href"), 60 &name = node.text(); 61 62 std::string effectiveName{name ? *name : url.value_or("")}; 63 64 md->addLink(Metadata::getLinkType(rel.value_or("")), 65 {effectiveName, url.value_or(effectiveName.c_str())}); 66 } 67 } 68 69 void LoadCategoryV1(XmlNode catNode, Index *ri) 70 { 71 const XmlString &name = catNode.attribute("name"); 72 73 Category *cat = new Category(name.value_or(""), ri); 74 std::unique_ptr<Category> ptr(cat); 75 76 for(XmlNode packNode = catNode.firstChild("reapack"); 77 packNode; packNode = packNode.nextSibling("reapack")) 78 LoadPackageV1(packNode, cat); 79 80 if(ri->addCategory(cat)) 81 ptr.release(); 82 } 83 84 void LoadPackageV1(XmlNode packNode, Category *cat) 85 { 86 const XmlString &type = packNode.attribute("type"), 87 &name = packNode.attribute("name"); 88 89 Package *pack = new Package(Package::getType(type.value_or("")), name.value_or(""), cat); 90 std::unique_ptr<Package> ptr(pack); 91 92 if(const XmlString &desc = packNode.attribute("desc")) 93 pack->setDescription(*desc); 94 95 for(XmlNode node = packNode.firstChild("version"); 96 node; node = node.nextSibling("version")) 97 LoadVersionV1(node, pack); 98 99 if(XmlNode node = packNode.firstChild("metadata")) 100 LoadMetadataV1(node, pack->metadata()); 101 102 if(cat->addPackage(pack)) 103 ptr.release(); 104 } 105 106 void LoadVersionV1(XmlNode verNode, Package *pkg) 107 { 108 const XmlString &name = verNode.attribute("name"); 109 Version *ver = new Version(name.value_or(""), pkg); 110 std::unique_ptr<Version> ptr(ver); 111 112 if(const XmlString &author = verNode.attribute("author")) 113 ver->setAuthor(*author); 114 115 if(const XmlString &time = verNode.attribute("time")) 116 ver->setTime(*time); 117 118 XmlNode node = verNode.firstChild("source"); 119 120 bool hasArm64Ec = false; 121 #if defined(_WIN32) && defined(_M_ARM64EC) 122 while(node) { 123 const char *platform = *node.attribute("platform"); 124 if(platform && Platform(platform) == Platform::Windows_arm64ec) { 125 hasArm64Ec = true; 126 break; 127 } 128 node = node.nextSibling("source"); 129 } 130 node = verNode.firstChild("source"); 131 #endif 132 133 while(node) { 134 LoadSourceV1(node, ver, hasArm64Ec); 135 node = node.nextSibling("source"); 136 } 137 138 node = verNode.firstChild("changelog"); 139 140 if(node) { 141 if(const XmlString &changelog = node.text()) 142 ver->setChangelog(*changelog); 143 } 144 145 if(pkg->addVersion(ver)) 146 ptr.release(); 147 } 148 149 void LoadSourceV1(XmlNode node, Version *ver, const bool hasArm64Ec) 150 { 151 const XmlString &platform = node.attribute("platform"), 152 &type = node.attribute("type"), 153 &file = node.attribute("file"), 154 &checksum = node.attribute("hash"), 155 &main = node.attribute("main"), 156 &url = node.text(); 157 158 Source *src = new Source(file.value_or(""), url.value_or(""), ver); 159 std::unique_ptr<Source> ptr(src); 160 161 src->setChecksum(checksum.value_or("")); 162 src->setPlatform(Platform(platform.value_or("all"), hasArm64Ec)); 163 src->setTypeOverride(Package::getType(type.value_or(""))); 164 165 int sections = 0; 166 std::string section; 167 std::istringstream mainStream(main.value_or("")); 168 while(std::getline(mainStream, section, '\x20')) 169 sections |= Source::getSection(section.c_str()); 170 src->setSections(sections); 171 172 if(ver->addSource(src)) 173 ptr.release(); 174 }