1 /**
2 * XSL Transforming input and output classes
3 *
4 * Authors:
5 * Bob Jamison <rjamison@titan.com>
6 *
7 * Copyright (C) 2004 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 //#########################################################################
28 /**
29 *
30 */
31 XsltStyleSheet::XsltStyleSheet(InputStream &xsltSource) throw (StreamException)
32 {
33 StringOutputStream outs;
34 pipeStream(xsltSource, outs);
35 std::string strBuf = outs.getString().raw();
36 xmlDocPtr doc = xmlParseMemory(strBuf.c_str(), strBuf.size());
37 stylesheet = xsltParseStylesheetDoc(doc);
38 //xmlFreeDoc(doc);
39 }
41 /**
42 *
43 */
44 XsltStyleSheet::~XsltStyleSheet()
45 {
46 xsltFreeStylesheet(stylesheet);
47 }
51 //#########################################################################
52 //# X S L T I N P U T S T R E A M
53 //#########################################################################
56 /**
57 *
58 */
59 XsltInputStream::XsltInputStream(InputStream &xmlSource, XsltStyleSheet &sheet)
60 throw (StreamException)
61 : BasicInputStream(xmlSource), stylesheet(sheet)
62 {
63 //Load the data
64 StringOutputStream outs;
65 pipeStream(source, outs);
66 std::string strBuf = outs.getString().raw();
68 //Do the processing
69 const char *params[1];
70 params[0] = NULL;
71 xmlDocPtr srcDoc = xmlParseMemory(strBuf.c_str(), strBuf.size());
72 xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params);
73 xmlDocDumpFormatMemory(resDoc, &outbuf, &outsize, 1);
74 outpos = 0;
76 //Free our mem
77 xmlFreeDoc(resDoc);
78 xmlFreeDoc(srcDoc);
79 }
81 /**
82 *
83 */
84 XsltInputStream::~XsltInputStream() throw (StreamException)
85 {
86 xmlFree(outbuf);
87 }
89 /**
90 * Returns the number of bytes that can be read (or skipped over) from
91 * this input stream without blocking by the next caller of a method for
92 * this input stream.
93 */
94 int XsltInputStream::available() throw (StreamException)
95 {
96 return outsize - outpos;
97 }
100 /**
101 * Closes this input stream and releases any system resources
102 * associated with the stream.
103 */
104 void XsltInputStream::close() throw (StreamException)
105 {
106 closed = true;
107 }
109 /**
110 * Reads the next byte of data from the input stream. -1 if EOF
111 */
112 int XsltInputStream::get() throw (StreamException)
113 {
114 if (closed)
115 return -1;
116 if (outpos >= outsize)
117 return -1;
118 int ch = (int) outbuf[outpos++];
119 return ch;
120 }
127 //#########################################################################
128 //# X S L T O U T P U T S T R E A M
129 //#########################################################################
131 /**
132 *
133 */
134 XsltOutputStream::XsltOutputStream(OutputStream &dest, XsltStyleSheet &sheet)
135 throw (StreamException)
136 : BasicOutputStream(dest), stylesheet(sheet)
137 {
138 flushed = false;
139 }
141 /**
142 *
143 */
144 XsltOutputStream::~XsltOutputStream() throw (StreamException)
145 {
146 //do not automatically close
147 }
149 /**
150 * Closes this output stream and releases any system resources
151 * associated with this stream.
152 */
153 void XsltOutputStream::close() throw (StreamException)
154 {
155 flush();
156 destination.close();
157 }
159 /**
160 * Flushes this output stream and forces any buffered output
161 * bytes to be written out.
162 */
163 void XsltOutputStream::flush() throw (StreamException)
164 {
165 if (flushed)
166 {
167 destination.flush();
168 return;
169 }
171 //Do the processing
172 xmlChar *resbuf;
173 int resSize;
174 const char *params[1];
175 params[0] = NULL;
176 xmlDocPtr srcDoc = xmlParseMemory(outbuf.raw().c_str(), outbuf.size());
177 xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params);
178 xmlDocDumpFormatMemory(resDoc, &resbuf, &resSize, 1);
179 /*
180 xmlErrorPtr err = xmlGetLastError();
181 if (err)
182 {
183 throw StreamException(err->message);
184 }
185 */
187 for (int i=0 ; i<resSize ; i++)
188 {
189 char ch = resbuf[i];
190 destination.put(ch);
191 }
193 //Free our mem
194 xmlFree(resbuf);
195 xmlFreeDoc(resDoc);
196 xmlFreeDoc(srcDoc);
197 destination.flush();
198 flushed = true;
199 }
201 /**
202 * Writes the specified byte to this output stream.
203 */
204 void XsltOutputStream::put(int ch) throw (StreamException)
205 {
206 gunichar uch = (gunichar) ch;
207 outbuf.push_back(uch);
208 }
214 } // namespace IO
215 } // namespace Inkscape
218 //#########################################################################
219 //# E N D O F F I L E
220 //#########################################################################