Code

fix 1243587 and misc fixes
[inkscape.git] / src / dom / lsimpl.cpp
1 /**
2  * Phoebe DOM Implementation.
3  *
4  * This is a C++ approximation of the W3C DOM model, which follows
5  * fairly closely the specifications in the various .idl files, copies of
6  * which are provided for reference.  Most important is this one:
7  *
8  * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
9  *
10  * Authors:
11  *   Bob Jamison
12  *
13  * Copyright (C) 2005-2007 Bob Jamison
14  *
15  *  This library is free software; you can redistribute it and/or
16  *  modify it under the terms of the GNU Lesser General Public
17  *  License as published by the Free Software Foundation; either
18  *  version 2.1 of the License, or (at your option) any later version.
19  *
20  *  This library is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  *  Lesser General Public License for more details.
24  *
25  *  You should have received a copy of the GNU Lesser General Public
26  *  License along with this library; if not, write to the Free Software
27  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28  */
30 #include "domimpl.h"
31 #include "events.h"
32 #include "traversal.h"
33 #include "lsimpl.h"
35 #include <stdarg.h>
37 namespace org
38 {
39 namespace w3c
40 {
41 namespace dom
42 {
43 namespace ls
44 {
48 /*#########################################################################
49 ## LSParserImpl
50 #########################################################################*/
53 /**
54  *
55  */
56 bool LSParserImpl::getBusy()
57 {
58     return false;
59 }
61 /**
62  *
63  */
64 DocumentPtr LSParserImpl::parse(const LSInput &input)
65                                 throw(dom::DOMException, LSException)
66 {
68     //#### Check the various inputs of 'input' in order, according
69     //# to the L&S spec
70     LSReader *lsreader = input.getCharacterStream();
71     if (lsreader)
72         {
73         DOMString buf;
74         while (true)
75             {
76             int ch = lsreader->get();
77             if (ch < 0)
78                 break;
79             buf.push_back((XMLCh)ch);
80             }
81         XmlReader reader;
82         DocumentPtr doc = reader.parse(buf);
83         return doc;
84         }
86     LSInputStream *inputStream = input.getByteStream();
87     if (inputStream)
88         {
89         DOMString buf;
90         while (true)
91             {
92             int ch = inputStream->get();
93             if (ch < 0)
94                 break;
95             buf.push_back((XMLCh)ch);
96             }
97         XmlReader reader;
98         DocumentPtr doc = reader.parse(buf);
99         return doc;
100         }
102     DOMString stringData = input.getStringData();
103     if (stringData.size() > 0)
104         {
105         XmlReader reader;
106         DocumentPtr doc = reader.parse(stringData);
107         return doc;
108         }
110     DOMString systemId = input.getSystemId();
111     if (systemId.size() > 0)
112         {
113         //lets not do this yet
114         return NULL;
115         }
117     DOMString publicId = input.getPublicId();
118     if (publicId.size() > 0)
119         {
120         //lets not do this yet
121         return NULL;
122         }
124     return NULL;
128 /**
129  *
130  */
131 DocumentPtr LSParserImpl::parseURI(const DOMString &uri)
132                                    throw(dom::DOMException, LSException)
134     return NULL;
137    /**
138  *
139  */
140 NodePtr LSParserImpl::parseWithContext(const LSInput &input,
141                                        const NodePtr contextArg,
142                                        unsigned short action)
143                                        throw(dom::DOMException, LSException)
145     return NULL;
150 //##################
151 //# Non-API methods
152 //##################
164 /*#########################################################################
165 ## LSSerializerImpl
166 #########################################################################*/
169 /**
170  *
171  */
172 bool LSSerializerImpl::write(
173                        const NodePtr nodeArg,
174                        const LSOutput &destination)
175                        throw (LSException)
177     outbuf = "";
178     indent = 0;
180     writeNode(nodeArg);
182     //## Check in order specified in the L&S specs
183     LSWriter *writer = destination.getCharacterStream();
184     if (writer)
185         {
186         for (unsigned int i=0 ; i<outbuf.size() ; i++)
187             {
188             int ch = outbuf[i];
189             writer->put(ch);
190             }
191         return true;
192         }
194     LSOutputStream *outputStream = destination.getByteStream();
195     if (outputStream)
196         {
197         for (unsigned int i=0 ; i<outbuf.size() ; i++)
198             {
199             int ch = outbuf[i];
200             writer->put(ch);
201             }
202         return true;
203         }
205     DOMString systemId = destination.getSystemId();
206     if (systemId.size() > 0)
207         {
208         //DO SOMETHING
209         return true;
210         }
212     return false;
215 /**
216  *
217  */
218 bool LSSerializerImpl::writeToURI(const NodePtr nodeArg,
219                                   const DOMString &uriArg)
220                                   throw(LSException)
222     outbuf = "";
223     indent = 0;
225     writeNode(nodeArg);
227     DOMString uri = uriArg;
228     char *fileName = (char *) uri.c_str(); //temporary hack
229     FILE *f = fopen(fileName, "rb");
230     if (!f)
231         return false;
232     for (unsigned int i=0 ; i<outbuf.size() ; i++)
233         {
234         int ch = outbuf[i];
235         fputc(ch, f);
236         }
237     fclose(f);
238     return false;
241 /**
242  *
243  */
244 DOMString LSSerializerImpl::writeToString(const NodePtr nodeArg)
245                                     throw(dom::DOMException, LSException)
247     outbuf = "";
248     indent = 0;
250     writeNode(nodeArg);
251     return outbuf;
256 //##################
257 //# Non-API methods
258 //##################
261 /**
262  *
263  */
264 void LSSerializerImpl::spaces()
266     for (int i=0 ; i<indent ; i++)
267         {
268         outbuf.push_back(' ');
269         }
272 /**
273  *
274  */
275 void LSSerializerImpl::po(char *fmt, ...)
277     char str[257];
278     va_list args;
279     va_start(args, fmt);
280     vsnprintf(str, 256,  fmt, args);
281     va_end(args) ;
283     outbuf.append(str);
287 void LSSerializerImpl::pos(const DOMString &str)
289     outbuf.append(str);
292 void LSSerializerImpl::poxml(const DOMString &str)
294     for (unsigned int i=0 ; i<str.size() ; i++)
295         {
296         XMLCh ch = (XMLCh) str[i];
297         if (ch == '&')
298             outbuf.append("&ampr;");
299         else if (ch == '<')
300             outbuf.append("&lt;");
301         else if (ch == '>')
302             outbuf.append("&gt;");
303         else if (ch == '"')
304             outbuf.append("&quot;");
305         else if (ch == '\'')
306             outbuf.append("&apos;");
307         else
308             outbuf.push_back(ch);
309         }
312 /**
313  *
314  */
315 void LSSerializerImpl::writeNode(const NodePtr nodeArg)
317     NodePtr node = nodeArg;
319     int type = node->getNodeType();
321     switch (type)
322         {
324         //#############
325         //# DOCUMENT
326         //#############
327         case Node::DOCUMENT_NODE:
328             {
329             DocumentPtr doc = dynamic_cast<Document *>(node.get());
330             writeNode(doc->getDocumentElement());
331             }
332         break;
334         //#############
335         //# TEXT
336         //#############
337         case Node::TEXT_NODE:
338             {
339             poxml(node->getNodeValue());
340             }
341         break;
344         //#############
345         //# CDATA
346         //#############
347         case Node::CDATA_SECTION_NODE:
348             {
349             pos("<![CDATA[");
350             poxml(node->getNodeValue());
351             pos("]]>");
352             }
353         break;
356         //#############
357         //# ELEMENT
358         //#############
359         case Node::ELEMENT_NODE:
360             {
362             indent+=2;
364             NamedNodeMap attributes = node->getAttributes();
365             int nrAttrs = attributes.getLength();
367             //### Start open tag
368             spaces();
369             po("<");
370             pos(node->getNodeName());
371             //if (nrAttrs>0)
372             //    pos(newLine);
374             //### Attributes
375             for (int i=0 ; i<nrAttrs ; i++)
376                 {
377                 NodePtr attr = attributes.item(i);
378                 spaces();
379                 pos(attr->getNodeName());
380                 po("=\"");
381                 pos(attr->getNodeValue());
382                 po("\"");
383                 //pos(newLine);
384                 }
386             //### Finish open tag
387             //if (nrAttrs>0)
388             //    spaces();
389             po(">");
390             //pos(newLine);
392             //### Contents
393             //spaces();
394             pos(node->getNodeValue());
396             //### Children
397             for (NodePtr child = node->getFirstChild() ;
398                  child.get() ;
399                  child=child->getNextSibling())
400                 {
401                 writeNode(child);
402                 }
404             //### Close tag
405             //spaces();
406             po("</");
407             pos(node->getNodeName());
408             po(">");
409             pos(newLine);
411             indent-=2;
412             }
413             break;
415         }//switch
428 }  //namespace ls
429 }  //namespace dom
430 }  //namespace w3c
431 }  //namespace org
437 /*#########################################################################
438 ## E N D    O F    F I L E
439 #########################################################################*/