reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

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 }