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;
125 }
128 /**
129 *
130 */
131 DocumentPtr LSParserImpl::parseURI(const DOMString &/*uri*/)
132 throw(dom::DOMException, LSException)
133 {
134 return NULL;
135 }
137 /**
138 *
139 */
140 NodePtr LSParserImpl::parseWithContext(const LSInput &/*input*/,
141 const NodePtr /*contextArg*/,
142 unsigned short /*action*/)
143 throw(dom::DOMException, LSException)
144 {
145 return NULL;
146 }
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)
176 {
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;
213 }
215 /**
216 *
217 */
218 bool LSSerializerImpl::writeToURI(const NodePtr nodeArg,
219 const DOMString &uriArg)
220 throw(LSException)
221 {
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;
239 }
241 /**
242 *
243 */
244 DOMString LSSerializerImpl::writeToString(const NodePtr nodeArg)
245 throw(dom::DOMException, LSException)
246 {
247 outbuf = "";
248 indent = 0;
250 writeNode(nodeArg);
251 return outbuf;
252 }
256 //##################
257 //# Non-API methods
258 //##################
261 /**
262 *
263 */
264 void LSSerializerImpl::spaces()
265 {
266 for (int i=0 ; i<indent ; i++)
267 {
268 outbuf.push_back(' ');
269 }
270 }
272 /**
273 *
274 */
275 void LSSerializerImpl::po(char const *fmt, ...)
276 {
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);
284 }
287 void LSSerializerImpl::pos(const DOMString &str)
288 {
289 outbuf.append(str);
290 }
292 void LSSerializerImpl::poxml(const DOMString &str)
293 {
294 for (unsigned int i=0 ; i<str.size() ; i++)
295 {
296 XMLCh ch = (XMLCh) str[i];
297 if (ch == '&')
298 outbuf.append("&r;");
299 else if (ch == '<')
300 outbuf.append("<");
301 else if (ch == '>')
302 outbuf.append(">");
303 else if (ch == '"')
304 outbuf.append(""");
305 else if (ch == '\'')
306 outbuf.append("'");
307 else
308 outbuf.push_back(ch);
309 }
310 }
312 /**
313 *
314 */
315 void LSSerializerImpl::writeNode(const NodePtr nodeArg)
316 {
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
417 }
428 } //namespace ls
429 } //namespace dom
430 } //namespace w3c
431 } //namespace org
437 /*#########################################################################
438 ## E N D O F F I L E
439 #########################################################################*/