OpenCPN Partial API docs
Loading...
Searching...
No Matches
catalog_parser.cpp
1/******************************************************************************
2 *
3 * Project: OpenCPN
4 *
5 ***************************************************************************
6 * Copyright (C) 2019 Alec Leamas *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
22 ***************************************************************************
23 */
24
25#include <sstream>
26
27#include <wx/log.h>
28
29#if defined(__MINGW32__) && defined(Yield)
30#undef Yield // from win.h, conflicts with mingw headers
31#endif
32
34#include "model/ocpn_utils.h"
36#include "pugixml.hpp"
37
38static void add_node(pugi::xml_node root, const std::string& name,
39 const std::string& value) {
40 auto child = root.append_child(name.c_str());
41 child.append_child(pugi::node_pcdata).set_value(value.c_str());
42}
43
46 auto root = doc.append_child("plugin");
47 root.append_attribute("version").set_value("1");
48
49 add_node(root, "name", name);
50 add_node(root, "version", version);
51 add_node(root, "release", release);
52 add_node(root, "summary", summary);
53 add_node(root, "api-version", api_version);
54 add_node(root, "open-source", openSource ? "true" : "false");
55 add_node(root, "is-imported", is_imported ? "true" : "false");
56 add_node(root, "author", author);
57 add_node(root, "source", author);
58 add_node(root, "info-url", info_url);
59 add_node(root, "description", description);
60 add_node(root, "target", target);
61 add_node(root, "target-version", target_version);
62 add_node(root, "target-arch", target_arch);
63 add_node(root, "tarball-url", tarball_url);
64 add_node(root, "tarball-checksum", checksum);
65
66 std::ostringstream ss;
67 doc.save(ss, " ");
68 return ss.str();
69}
70
71static void ParseValue(pugi::xml_node node, const std::string& name,
72 std::string& value) {
73 auto child = node.child(name.c_str());
74 if (child) value = ocpn::trim(child.first_child().value());
75}
76
77static void ParseBool(pugi::xml_node node, const std::string& name,
78 bool& value) {
79 auto child = node.child(name.c_str());
80 if (child) {
81 auto text = ocpn::trim(child.first_child().value());
82 value = text == "yes" || text == "true";
83 }
84}
85
86bool ParsePlugin(pugi::xml_node root, PluginMetadata& plugin) {
87 ParseValue(root, "name", plugin.name);
88 ParseValue(root, "version", plugin.version);
89 ParseValue(root, "release", plugin.release);
90 ParseValue(root, "summary", plugin.summary);
91 ParseValue(root, "api-version", plugin.api_version);
92 ParseValue(root, "author", plugin.author);
93 ParseValue(root, "description", plugin.description);
94 ParseValue(root, "source", plugin.source);
95 ParseValue(root, "tarball-url", plugin.tarball_url);
96 ParseValue(root, "info-url", plugin.info_url);
97 ParseValue(root, "target", plugin.target);
98 ParseValue(root, "target-version", plugin.target_version);
99 ParseValue(root, "target-arch", plugin.target_arch);
100 ParseValue(root, "target-checksum", plugin.checksum);
101 ParseBool(root, "open-source", plugin.openSource);
102 ParseBool(root, "is-imported", plugin.is_imported);
103 return root.child("name") ? true : false;
104}
105
106bool ParsePlugin(const std::string& xml, PluginMetadata& plugin) {
108 doc.load_string(xml.c_str());
109 auto node = doc.child("plugin");
110 if (!node) {
111 wxLogWarning("Trying to parse plugin without root node");
112 return false;
113 }
114 return ParsePlugin(doc.child("plugin"), plugin);
115}
116
117bool ParseCatalog(const std::string xml, CatalogCtx* ctx) {
118 PluginMetadata* plugin = 0;
119
121 doc.load_string(xml.c_str());
122
123 pugi::xml_node nodes = doc.child("plugins");
124 for (pugi::xml_node node = nodes.first_child(); node;
125 node = node.next_sibling()) {
126 if (!strcmp(node.name(), "version") && ctx->version == "") {
127 ctx->version = ocpn::trim(node.first_child().value());
128 } else if (strcmp(node.name(), "date") == 0 && ctx->date == "") {
129 ctx->date = ocpn::trim(node.first_child().value());
130 } else if (strcmp(node.name(), "meta-url") == 0) {
131 ctx->meta_url = ocpn::trim(node.first_child().value());
132 } else if (!strcmp(node.name(), "plugin")) {
133 if (ctx->meta_url != "") {
134 ctx->meta_urls.push_back(ctx->meta_url);
135 ctx->meta_url = "";
136 } else {
137 if (plugin) {
138 ctx->plugins.push_back(*plugin);
139 delete plugin;
140 }
141 plugin = new PluginMetadata;
142 }
143 auto meta_url = node.child("meta-url");
144 if (meta_url) {
145 auto url = ocpn::trim(meta_url.first_child().value());
146 ctx->meta_url = url;
147 }
148 ParsePlugin(node, *plugin);
149 }
150 }
151 // capture last plugin
152 if (plugin) {
153 ctx->plugins.push_back(*plugin);
154 delete plugin;
155 } else {
156 if (ctx->meta_url != "") {
157 ctx->meta_urls.push_back(ctx->meta_url);
158 ctx->meta_url = "";
159 }
160 }
161 return true;
162}
Plugin catalog management: Build the runtime catalog, handling downloads as required.
Datatypes and methods to parse ocpn-plugins.xml XML data, either complete catalog or a single plugin.
The result from parsing the xml catalog i.
Plugin metadata, reflects the xml format directly.
std::string to_string()
Return printable XML representation.