summaryrefslogtreecommitdiff
path: root/icespider/xslt
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2016-08-21 13:06:27 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2016-08-21 13:06:27 +0100
commitb388a5537f2e3b459021118fcda18e2a58da3492 (patch)
tree52f8beda2b103d5411b63cef900060a7433708ae /icespider/xslt
parentAllow inclusion of user headers (diff)
downloadicespider-b388a5537f2e3b459021118fcda18e2a58da3492.tar.bz2
icespider-b388a5537f2e3b459021118fcda18e2a58da3492.tar.xz
icespider-b388a5537f2e3b459021118fcda18e2a58da3492.zip
Add support for custom output serializers
Diffstat (limited to 'icespider/xslt')
-rw-r--r--icespider/xslt/Jamfile.jam22
-rw-r--r--icespider/xslt/exslt.cpp17
-rw-r--r--icespider/xslt/xsltStreamSerializer.cpp70
-rw-r--r--icespider/xslt/xsltStreamSerializer.h34
4 files changed, 143 insertions, 0 deletions
diff --git a/icespider/xslt/Jamfile.jam b/icespider/xslt/Jamfile.jam
new file mode 100644
index 0000000..1bf62a8
--- /dev/null
+++ b/icespider/xslt/Jamfile.jam
@@ -0,0 +1,22 @@
+lib adhocutil : : : : <include>/usr/include/adhocutil ;
+lib slicer-xml : : : : <include>/usr/include/slicer ;
+lib boost_system ;
+lib IceUtil ;
+lib xslt ;
+lib exslt ;
+
+lib icespider-xslt :
+ [ glob-tree *.cpp : bin ]
+ :
+ <library>adhocutil
+ <library>slicer-xml
+ <library>boost_system
+ <library>IceUtil
+ <library>xslt
+ <library>exslt
+ <library>../..//libxmlpp
+ : :
+ <include>.
+ <library>../..//libxmlpp
+ ;
+
diff --git a/icespider/xslt/exslt.cpp b/icespider/xslt/exslt.cpp
new file mode 100644
index 0000000..63bd0d1
--- /dev/null
+++ b/icespider/xslt/exslt.cpp
@@ -0,0 +1,17 @@
+#include <libexslt/exslt.h>
+#include <libxslt/transform.h>
+
+static void initLibXml() __attribute__((constructor(102)));
+void initLibXml()
+{
+ xmlInitParser();
+ exsltRegisterAll();
+}
+
+static void cleanupLibXml() __attribute__((destructor(102)));
+void cleanupLibXml()
+{
+ xsltCleanupGlobals();
+ xmlCleanupParser();
+}
+
diff --git a/icespider/xslt/xsltStreamSerializer.cpp b/icespider/xslt/xsltStreamSerializer.cpp
new file mode 100644
index 0000000..bbe3943
--- /dev/null
+++ b/icespider/xslt/xsltStreamSerializer.cpp
@@ -0,0 +1,70 @@
+#include "xsltStreamSerializer.h"
+#include <libxslt/xsltInternals.h>
+#include <libxml/HTMLtree.h>
+#include <factory.impl.h>
+
+namespace IceSpider {
+ static int xmlstrmclosecallback(void * context)
+ {
+ ((std::ostream*)context)->flush();
+ return 0;
+ }
+
+ static int xmlstrmwritecallback(void * context, const char * buffer, int len)
+ {
+ ((std::ostream*)context)->write(buffer, len);
+ return len;
+ }
+
+ XsltStreamSerializer::IceSpiderFactory::IceSpiderFactory(const char * path) :
+ stylesheet(xsltParseStylesheetFile(BAD_CAST path))
+ {
+ if (!stylesheet) {
+ throw xmlpp::exception("Failed to load stylesheet");
+ }
+ }
+
+ XsltStreamSerializer::IceSpiderFactory::~IceSpiderFactory()
+ {
+ xsltFreeStylesheet(stylesheet);
+ }
+
+ XsltStreamSerializer *
+ XsltStreamSerializer::IceSpiderFactory::create(std::ostream & strm) const
+ {
+ return new XsltStreamSerializer(strm, stylesheet);
+ }
+
+ XsltStreamSerializer::XsltStreamSerializer(std::ostream & os, xsltStylesheet * ss) :
+ Slicer::XmlDocumentSerializer(doc),
+ strm(os),
+ doc(nullptr),
+ stylesheet(ss)
+ {
+ }
+
+ XsltStreamSerializer::~XsltStreamSerializer()
+ {
+ delete doc;
+ }
+
+ void
+ XsltStreamSerializer::Serialize(Slicer::ModelPartPtr mp)
+ {
+ Slicer::XmlDocumentSerializer::Serialize(mp);
+ auto result = xsltApplyStylesheet(stylesheet, doc->cobj(), nullptr);
+ if (!result) {
+ throw xmlpp::exception("Failed to apply XSL transform");
+ }
+ xmlOutputBufferPtr buf = xmlOutputBufferCreateIO(xmlstrmwritecallback, xmlstrmclosecallback, &strm, NULL);
+ if (xmlStrcmp(stylesheet->method, BAD_CAST "html") == 0) {
+ htmlDocContentDumpFormatOutput(buf, result, (const char *) stylesheet->encoding, 0);
+ }
+ else {
+ xmlNodeDumpOutput(buf, result, result->children, 0, 0, (const char *) stylesheet->encoding);
+ }
+ xmlOutputBufferClose(buf);
+ xmlFreeDoc(result);
+ }
+}
+
diff --git a/icespider/xslt/xsltStreamSerializer.h b/icespider/xslt/xsltStreamSerializer.h
new file mode 100644
index 0000000..d8000d1
--- /dev/null
+++ b/icespider/xslt/xsltStreamSerializer.h
@@ -0,0 +1,34 @@
+#ifndef ICESPIDER_CORE_XSLTSTREAMSERIALIZER_H
+#define ICESPIDER_CORE_XSLTSTREAMSERIALIZER_H
+
+#include <slicer/xml/serializer.h>
+#include <visibility.h>
+#include <libxslt/transform.h>
+
+namespace IceSpider {
+ class DLL_PUBLIC XsltStreamSerializer : public Slicer::XmlDocumentSerializer {
+ public:
+ class IceSpiderFactory : public Slicer::StreamSerializerFactory {
+ public:
+ IceSpiderFactory(const char *);
+ ~IceSpiderFactory();
+
+ XsltStreamSerializer * create(std::ostream &) const override;
+
+ xsltStylesheet * stylesheet;
+ };
+
+ XsltStreamSerializer(std::ostream &, xsltStylesheet *);
+ ~XsltStreamSerializer();
+
+ void Serialize(Slicer::ModelPartPtr mp) override;
+
+ protected:
+ std::ostream & strm;
+ xmlpp::Document * doc;
+ xsltStylesheet * stylesheet;
+ };
+}
+
+#endif
+