summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/XSLTUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/utils/XSLTUtils.cpp')
-rw-r--r--xbmc/utils/XSLTUtils.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/xbmc/utils/XSLTUtils.cpp b/xbmc/utils/XSLTUtils.cpp
new file mode 100644
index 0000000..ba069ba
--- /dev/null
+++ b/xbmc/utils/XSLTUtils.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "XSLTUtils.h"
+#include "log.h"
+#include <libxslt/xslt.h>
+#include <libxslt/transform.h>
+
+#ifndef TARGET_WINDOWS
+#include <iostream>
+#endif
+
+#define TMP_BUF_SIZE 512
+void err(void *ctx, const char *msg, ...) {
+ char string[TMP_BUF_SIZE];
+ va_list arg_ptr;
+ va_start(arg_ptr, msg);
+ vsnprintf(string, TMP_BUF_SIZE, msg, arg_ptr);
+ va_end(arg_ptr);
+ CLog::Log(LOGDEBUG, "XSLT: {}", string);
+}
+
+XSLTUtils::XSLTUtils()
+{
+ // initialize libxslt
+ xmlSubstituteEntitiesDefault(1);
+ xmlLoadExtDtdDefaultValue = 0;
+ xsltSetGenericErrorFunc(NULL, err);
+}
+
+XSLTUtils::~XSLTUtils()
+{
+ if (m_xmlInput)
+ xmlFreeDoc(m_xmlInput);
+ if (m_xmlOutput)
+ xmlFreeDoc(m_xmlOutput);
+ if (m_xsltStylesheet)
+ xsltFreeStylesheet(m_xsltStylesheet);
+}
+
+bool XSLTUtils::XSLTTransform(std::string& output)
+{
+ const char *params[16+1];
+ params[0] = NULL;
+ m_xmlOutput = xsltApplyStylesheet(m_xsltStylesheet, m_xmlInput, params);
+ if (!m_xmlOutput)
+ {
+ CLog::Log(LOGDEBUG, "XSLT: xslt transformation failed");
+ return false;
+ }
+
+ xmlChar *xmlResultBuffer = NULL;
+ int xmlResultLength = 0;
+ int res = xsltSaveResultToString(&xmlResultBuffer, &xmlResultLength, m_xmlOutput, m_xsltStylesheet);
+ if (res == -1)
+ {
+ xmlFree(xmlResultBuffer);
+ return false;
+ }
+
+ output.append((const char *)xmlResultBuffer, xmlResultLength);
+ xmlFree(xmlResultBuffer);
+
+ return true;
+}
+
+bool XSLTUtils::SetInput(const std::string& input)
+{
+ m_xmlInput = xmlParseMemory(input.c_str(), input.size());
+ if (!m_xmlInput)
+ return false;
+ return true;
+}
+
+bool XSLTUtils::SetStylesheet(const std::string& stylesheet)
+{
+ if (m_xsltStylesheet) {
+ xsltFreeStylesheet(m_xsltStylesheet);
+ m_xsltStylesheet = NULL;
+ }
+
+ m_xmlStylesheet = xmlParseMemory(stylesheet.c_str(), stylesheet.size());
+ if (!m_xmlStylesheet)
+ {
+ CLog::Log(LOGDEBUG, "could not xmlParseMemory stylesheetdoc");
+ return false;
+ }
+
+ m_xsltStylesheet = xsltParseStylesheetDoc(m_xmlStylesheet);
+ if (!m_xsltStylesheet) {
+ CLog::Log(LOGDEBUG, "could not parse stylesheetdoc");
+ xmlFree(m_xmlStylesheet);
+ m_xmlStylesheet = NULL;
+ return false;
+ }
+
+ return true;
+}