1 /**
2 * XSL Transforming input and output classes
3 *
4 * Authors:
5 * Bob Jamison <ishmalius@gmail.com>
6 *
7 * Copyright (C) 2004-2008 Inkscape.org
8 *
9 * Released under GNU GPL, read the file 'COPYING' for more information
10 */
13 #include "xsltstream.h"
14 #include "stringstream.h"
15 #include <libxslt/transform.h>
20 namespace Inkscape
21 {
22 namespace IO
23 {
25 //#########################################################################
26 //# X S L T S T Y L E S H E E T
27 //#########################################################################
29 /**
30 *
31 */
32 XsltStyleSheet::XsltStyleSheet(InputStream &xsltSource)
33 throw (StreamException)
34 : stylesheet(NULL)
35 {
36 if (!read(xsltSource)) {
37 throw StreamException("read failed");
38 }
39 }
41 /**
42 *
43 */
44 XsltStyleSheet::XsltStyleSheet()
45 : stylesheet(NULL)
46 {
47 }
51 /**
52 *
53 */
54 bool XsltStyleSheet::read(InputStream &xsltSource)
55 {
56 StringOutputStream outs;
57 pipeStream(xsltSource, outs);
58 std::string strBuf = outs.getString().raw();
59 xmlDocPtr doc = xmlParseMemory(strBuf.c_str(), strBuf.size());
60 stylesheet = xsltParseStylesheetDoc(doc);
61 //following not necessary. handled by xsltFreeStylesheet(stylesheet);
62 //xmlFreeDoc(doc);
63 if (!stylesheet)
64 return false;
65 return true;
66 }
69 /**
70 *
71 */
72 XsltStyleSheet::~XsltStyleSheet()
73 {
74 if (stylesheet)
75 xsltFreeStylesheet(stylesheet);
76 }
80 //#########################################################################
81 //# X S L T I N P U T S T R E A M
82 //#########################################################################
85 /**
86 *
87 */
88 XsltInputStream::XsltInputStream(InputStream &xmlSource, XsltStyleSheet &sheet)
89 throw (StreamException)
90 : BasicInputStream(xmlSource), stylesheet(sheet)
91 {
92 //Load the data
93 StringOutputStream outs;
94 pipeStream(source, outs);
95 std::string strBuf = outs.getString().raw();
97 //Do the processing
98 const char *params[1];
99 params[0] = NULL;
100 xmlDocPtr srcDoc = xmlParseMemory(strBuf.c_str(), strBuf.size());
101 xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params);
102 xmlDocDumpFormatMemory(resDoc, &outbuf, &outsize, 1);
103 outpos = 0;
105 //Free our mem
106 xmlFreeDoc(resDoc);
107 xmlFreeDoc(srcDoc);
108 }
110 /**
111 *
112 */
113 XsltInputStream::~XsltInputStream() throw (StreamException)
114 {
115 xmlFree(outbuf);
116 }
118 /**
119 * Returns the number of bytes that can be read (or skipped over) from
120 * this input stream without blocking by the next caller of a method for
121 * this input stream.
122 */
123 int XsltInputStream::available() throw (StreamException)
124 {
125 return outsize - outpos;
126 }
129 /**
130 * Closes this input stream and releases any system resources
131 * associated with the stream.
132 */
133 void XsltInputStream::close() throw (StreamException)
134 {
135 closed = true;
136 }
138 /**
139 * Reads the next byte of data from the input stream. -1 if EOF
140 */
141 int XsltInputStream::get() throw (StreamException)
142 {
143 if (closed)
144 return -1;
145 if (outpos >= outsize)
146 return -1;
147 int ch = (int) outbuf[outpos++];
148 return ch;
149 }
156 //#########################################################################
157 //# X S L T O U T P U T S T R E A M
158 //#########################################################################
160 /**
161 *
162 */
163 XsltOutputStream::XsltOutputStream(OutputStream &dest, XsltStyleSheet &sheet)
164 throw (StreamException)
165 : BasicOutputStream(dest), stylesheet(sheet)
166 {
167 flushed = false;
168 }
170 /**
171 *
172 */
173 XsltOutputStream::~XsltOutputStream() throw (StreamException)
174 {
175 //do not automatically close
176 }
178 /**
179 * Closes this output stream and releases any system resources
180 * associated with this stream.
181 */
182 void XsltOutputStream::close() throw (StreamException)
183 {
184 flush();
185 destination.close();
186 }
188 /**
189 * Flushes this output stream and forces any buffered output
190 * bytes to be written out.
191 */
192 void XsltOutputStream::flush() throw (StreamException)
193 {
194 if (flushed)
195 {
196 destination.flush();
197 return;
198 }
200 //Do the processing
201 xmlChar *resbuf;
202 int resSize;
203 const char *params[1];
204 params[0] = NULL;
205 xmlDocPtr srcDoc = xmlParseMemory(outbuf.raw().c_str(), outbuf.size());
206 xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params);
207 xmlDocDumpFormatMemory(resDoc, &resbuf, &resSize, 1);
208 /*
209 xmlErrorPtr err = xmlGetLastError();
210 if (err)
211 {
212 throw StreamException(err->message);
213 }
214 */
216 for (int i=0 ; i<resSize ; i++)
217 {
218 char ch = resbuf[i];
219 destination.put(ch);
220 }
222 //Free our mem
223 xmlFree(resbuf);
224 xmlFreeDoc(resDoc);
225 xmlFreeDoc(srcDoc);
226 destination.flush();
227 flushed = true;
228 }
230 /**
231 * Writes the specified byte to this output stream.
232 */
233 void XsltOutputStream::put(int ch) throw (StreamException)
234 {
235 gunichar uch = (gunichar) ch;
236 outbuf.push_back(uch);
237 }
243 } // namespace IO
244 } // namespace Inkscape
247 //#########################################################################
248 //# E N D O F F I L E
249 //#########################################################################