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>
36 #include <cstdio>
38 namespace org
39 {
40 namespace w3c
41 {
42 namespace dom
43 {
44 namespace ls
45 {
49 /*#########################################################################
50 ## LSParserImpl
51 #########################################################################*/
54 /**
55 *
56 */
57 bool LSParserImpl::getBusy()
58 {
59 return false;
60 }
62 /**
63 *
64 */
65 DocumentPtr LSParserImpl::parse(const LSInput &input)
66 throw(dom::DOMException, LSException)
67 {
69 //#### Check the various inputs of 'input' in order, according
70 //# to the L&S spec
71 LSReader *lsreader = input.getCharacterStream();
72 if (lsreader)
73 {
74 DOMString buf;
75 while (true)
76 {
77 int ch = lsreader->get();
78 if (ch < 0)
79 break;
80 buf.push_back((XMLCh)ch);
81 }
82 XmlReader reader;
83 DocumentPtr doc = reader.parse(buf);
84 return doc;
85 }
87 LSInputStream *inputStream = input.getByteStream();
88 if (inputStream)
89 {
90 DOMString buf;
91 while (true)
92 {
93 int ch = inputStream->get();
94 if (ch < 0)
95 break;
96 buf.push_back((XMLCh)ch);
97 }
98 XmlReader reader;
99 DocumentPtr doc = reader.parse(buf);
100 return doc;
101 }
103 DOMString stringData = input.getStringData();
104 if (stringData.size() > 0)
105 {
106 XmlReader reader;
107 DocumentPtr doc = reader.parse(stringData);
108 return doc;
109 }
111 DOMString systemId = input.getSystemId();
112 if (systemId.size() > 0)
113 {
114 //lets not do this yet
115 return NULL;
116 }
118 DOMString publicId = input.getPublicId();
119 if (publicId.size() > 0)
120 {
121 //lets not do this yet
122 return NULL;
123 }
125 return NULL;
126 }
129 /**
130 *
131 */
132 DocumentPtr LSParserImpl::parseURI(const DOMString &/*uri*/)
133 throw(dom::DOMException, LSException)
134 {
135 return NULL;
136 }
138 /**
139 *
140 */
141 NodePtr LSParserImpl::parseWithContext(const LSInput &/*input*/,
142 const NodePtr /*contextArg*/,
143 unsigned short /*action*/)
144 throw(dom::DOMException, LSException)
145 {
146 return NULL;
147 }
151 //##################
152 //# Non-API methods
153 //##################
165 /*#########################################################################
166 ## LSSerializerImpl
167 #########################################################################*/
170 /**
171 *
172 */
173 bool LSSerializerImpl::write(
174 const NodePtr nodeArg,
175 const LSOutput &destination)
176 throw (LSException)
177 {
178 outbuf = "";
179 indent = 0;
181 writeNode(nodeArg);
183 //## Check in order specified in the L&S specs
184 LSWriter *writer = destination.getCharacterStream();
185 if (writer)
186 {
187 for (unsigned int i=0 ; i<outbuf.size() ; i++)
188 {
189 int ch = outbuf[i];
190 writer->put(ch);
191 }
192 return true;
193 }
195 LSOutputStream *outputStream = destination.getByteStream();
196 if (outputStream)
197 {
198 for (unsigned int i=0 ; i<outbuf.size() ; i++)
199 {
200 int ch = outbuf[i];
201 writer->put(ch);
202 }
203 return true;
204 }
206 DOMString systemId = destination.getSystemId();
207 if (systemId.size() > 0)
208 {
209 //DO SOMETHING
210 return true;
211 }
213 return false;
214 }
216 /**
217 *
218 */
219 bool LSSerializerImpl::writeToURI(const NodePtr nodeArg,
220 const DOMString &uriArg)
221 throw(LSException)
222 {
223 outbuf = "";
224 indent = 0;
226 writeNode(nodeArg);
228 DOMString uri = uriArg;
229 char *fileName = (char *) uri.c_str(); //temporary hack
230 FILE *f = fopen(fileName, "rb");
231 if (!f)
232 return false;
233 for (unsigned int i=0 ; i<outbuf.size() ; i++)
234 {
235 int ch = outbuf[i];
236 fputc(ch, f);
237 }
238 fclose(f);
239 return false;
240 }
242 /**
243 *
244 */
245 DOMString LSSerializerImpl::writeToString(const NodePtr nodeArg)
246 throw(dom::DOMException, LSException)
247 {
248 outbuf = "";
249 indent = 0;
251 writeNode(nodeArg);
252 return outbuf;
253 }
257 //##################
258 //# Non-API methods
259 //##################
262 /**
263 *
264 */
265 void LSSerializerImpl::spaces()
266 {
267 for (int i=0 ; i<indent ; i++)
268 {
269 outbuf.push_back(' ');
270 }
271 }
273 /**
274 *
275 */
276 void LSSerializerImpl::po(char const *fmt, ...)
277 {
278 char str[257];
279 va_list args;
280 va_start(args, fmt);
281 vsnprintf(str, 256, fmt, args);
282 va_end(args) ;
284 outbuf.append(str);
285 }
288 void LSSerializerImpl::pos(const DOMString &str)
289 {
290 outbuf.append(str);
291 }
293 void LSSerializerImpl::poxml(const DOMString &str)
294 {
295 for (unsigned int i=0 ; i<str.size() ; i++)
296 {
297 XMLCh ch = (XMLCh) str[i];
298 if (ch == '&')
299 outbuf.append("&r;");
300 else if (ch == '<')
301 outbuf.append("<");
302 else if (ch == '>')
303 outbuf.append(">");
304 else if (ch == '"')
305 outbuf.append(""");
306 else if (ch == '\'')
307 outbuf.append("'");
308 else
309 outbuf.push_back(ch);
310 }
311 }
313 /**
314 *
315 */
316 void LSSerializerImpl::writeNode(const NodePtr nodeArg)
317 {
318 NodePtr node = nodeArg;
320 int type = node->getNodeType();
322 switch (type)
323 {
325 //#############
326 //# DOCUMENT
327 //#############
328 case Node::DOCUMENT_NODE:
329 {
330 DocumentPtr doc = dynamic_cast<Document *>(node.get());
331 writeNode(doc->getDocumentElement());
332 }
333 break;
335 //#############
336 //# TEXT
337 //#############
338 case Node::TEXT_NODE:
339 {
340 poxml(node->getNodeValue());
341 }
342 break;
345 //#############
346 //# CDATA
347 //#############
348 case Node::CDATA_SECTION_NODE:
349 {
350 pos("<![CDATA[");
351 poxml(node->getNodeValue());
352 pos("]]>");
353 }
354 break;
357 //#############
358 //# ELEMENT
359 //#############
360 case Node::ELEMENT_NODE:
361 {
363 indent+=2;
365 NamedNodeMap attributes = node->getAttributes();
366 int nrAttrs = attributes.getLength();
368 //### Start open tag
369 spaces();
370 po("<");
371 pos(node->getNodeName());
372 //if (nrAttrs>0)
373 // pos(newLine);
375 //### Attributes
376 for (int i=0 ; i<nrAttrs ; i++)
377 {
378 NodePtr attr = attributes.item(i);
379 spaces();
380 pos(attr->getNodeName());
381 po("=\"");
382 pos(attr->getNodeValue());
383 po("\"");
384 //pos(newLine);
385 }
387 //### Finish open tag
388 //if (nrAttrs>0)
389 // spaces();
390 po(">");
391 //pos(newLine);
393 //### Contents
394 //spaces();
395 pos(node->getNodeValue());
397 //### Children
398 for (NodePtr child = node->getFirstChild() ;
399 child.get() ;
400 child=child->getNextSibling())
401 {
402 writeNode(child);
403 }
405 //### Close tag
406 //spaces();
407 po("</");
408 pos(node->getNodeName());
409 po(">");
410 pos(newLine);
412 indent-=2;
413 }
414 break;
416 }//switch
418 }
429 } //namespace ls
430 } //namespace dom
431 } //namespace w3c
432 } //namespace org
438 /*#########################################################################
439 ## E N D O F F I L E
440 #########################################################################*/