// SPDX-License-Identifier: GPL-2.0-or-later /* * XSL Transforming input and output classes * * Authors: * Bob Jamison * * 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 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