diff options
Diffstat (limited to 'src/io/stream/xsltstream.cpp')
-rw-r--r-- | src/io/stream/xsltstream.cpp | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/src/io/stream/xsltstream.cpp b/src/io/stream/xsltstream.cpp new file mode 100644 index 0000000..882db30 --- /dev/null +++ b/src/io/stream/xsltstream.cpp @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * XSL Transforming input and output classes + * + * Authors: + * Bob Jamison <ishmalius@gmail.com> + * + * Copyright (C) 2004-2008 Inkscape.org + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + + +#include "xsltstream.h" +#include "stringstream.h" +#include <libxslt/transform.h> + + + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# X S L T S T Y L E S H E E T +//######################################################################### + +/** + * + */ +XsltStyleSheet::XsltStyleSheet(InputStream &xsltSource) + + : stylesheet(nullptr) +{ + if (!read(xsltSource)) { + throw StreamException("read failed"); + } +} + +/** + * + */ +XsltStyleSheet::XsltStyleSheet() + : stylesheet(nullptr) +{ +} + + + +/** + * + */ +bool XsltStyleSheet::read(InputStream &xsltSource) +{ + StringOutputStream outs; + pipeStream(xsltSource, outs); + std::string strBuf = outs.getString().raw(); + xmlDocPtr doc = xmlParseMemory(strBuf.c_str(), strBuf.size()); + stylesheet = xsltParseStylesheetDoc(doc); + //following not necessary. handled by xsltFreeStylesheet(stylesheet); + //xmlFreeDoc(doc); + if (!stylesheet) + return false; + return true; +} + + +/** + * + */ +XsltStyleSheet::~XsltStyleSheet() +{ + if (stylesheet) + xsltFreeStylesheet(stylesheet); +} + + + +//######################################################################### +//# X S L T I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +XsltInputStream::XsltInputStream(InputStream &xmlSource, XsltStyleSheet &sheet) + : BasicInputStream(xmlSource), stylesheet(sheet) +{ + //Load the data + StringOutputStream outs; + pipeStream(source, outs); + std::string strBuf = outs.getString().raw(); + + //Do the processing + const char *params[1]; + params[0] = nullptr; + xmlDocPtr srcDoc = xmlParseMemory(strBuf.c_str(), strBuf.size()); + xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); + xmlDocDumpFormatMemory(resDoc, &outbuf, &outsize, 1); + outpos = 0; + + //Free our mem + xmlFreeDoc(resDoc); + xmlFreeDoc(srcDoc); +} + +/** + * + */ +XsltInputStream::~XsltInputStream() +{ + xmlFree(outbuf); +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int XsltInputStream::available() +{ + return outsize - outpos; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void XsltInputStream::close() +{ + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int XsltInputStream::get() +{ + if (closed) + return -1; + if (outpos >= outsize) + return -1; + int ch = (int) outbuf[outpos++]; + return ch; +} + + + + + + +//######################################################################### +//# X S L T O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +XsltOutputStream::XsltOutputStream(OutputStream &dest, XsltStyleSheet &sheet) + : BasicOutputStream(dest), stylesheet(sheet) +{ + flushed = false; +} + +/** + * + */ +XsltOutputStream::~XsltOutputStream() +{ + //do not automatically close +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void XsltOutputStream::close() +{ + flush(); + destination.close(); +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void XsltOutputStream::flush() +{ + if (flushed) + { + destination.flush(); + return; + } + + //Do the processing + xmlChar *resbuf; + int resSize; + const char *params[1]; + params[0] = nullptr; + xmlDocPtr srcDoc = xmlParseMemory(outbuf.raw().c_str(), outbuf.size()); + xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); + xmlDocDumpFormatMemory(resDoc, &resbuf, &resSize, 1); + /* + xmlErrorPtr err = xmlGetLastError(); + if (err) + { + throw StreamException(err->message); + } + */ + + for (int i=0 ; i<resSize ; i++) + { + char ch = resbuf[i]; + destination.put(ch); + } + + //Free our mem + xmlFree(resbuf); + xmlFreeDoc(resDoc); + xmlFreeDoc(srcDoc); + destination.flush(); + flushed = true; +} + +/** + * Writes the specified byte to this output stream. + */ +int XsltOutputStream::put(char ch) +{ + outbuf.push_back(ch); + return 1; +} + + + + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### |