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 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 "lsimpl.h"
32 #include <stdarg.h>
34 namespace org
35 {
36 namespace w3c
37 {
38 namespace dom
39 {
40 namespace ls
41 {
45 /*#########################################################################
46 ## LSParserImpl
47 #########################################################################*/
50 /**
51 *
52 */
53 bool LSParserImpl::getBusy()
54 {
55 return false;
56 }
58 /**
59 *
60 */
61 Document *LSParserImpl::parse(const LSInput &input)
62 throw(dom::DOMException, LSException)
63 {
65 //#### Check the various inputs of 'input' in order, according
66 //# to the L&S spec
67 LSReader *lsreader = input.getCharacterStream();
68 if (lsreader)
69 {
70 DOMString buf;
71 while (true)
72 {
73 int ch = lsreader->get();
74 if (ch < 0)
75 break;
76 buf.push_back(ch);
77 }
78 XmlReader reader;
79 Document *doc = reader.parse(buf);
80 return doc;
81 }
83 LSInputStream *inputStream = input.getByteStream();
84 if (inputStream)
85 {
86 DOMString buf;
87 while (true)
88 {
89 int ch = inputStream->get();
90 if (ch < 0)
91 break;
92 buf.push_back(ch);
93 }
94 XmlReader reader;
95 Document *doc = reader.parse(buf);
96 return doc;
97 }
99 DOMString stringData = input.getStringData();
100 if (stringData.size() > 0)
101 {
102 XmlReader reader;
103 Document *doc = reader.parse(stringData);
104 return doc;
105 }
107 DOMString systemId = input.getSystemId();
108 if (systemId.size() > 0)
109 {
110 //lets not do this yet
111 return NULL;
112 }
114 DOMString publicId = input.getPublicId();
115 if (publicId.size() > 0)
116 {
117 //lets not do this yet
118 return NULL;
119 }
121 return NULL;
122 }
125 /**
126 *
127 */
128 Document *LSParserImpl::parseURI(const DOMString &uri)
129 throw(dom::DOMException, LSException)
130 {
131 return NULL;
132 }
134 /**
135 *
136 */
137 Node *LSParserImpl::parseWithContext(const LSInput &input,
138 const Node *contextArg,
139 unsigned short action)
140 throw(dom::DOMException, LSException)
141 {
142 return NULL;
143 }
147 //##################
148 //# Non-API methods
149 //##################
161 /*#########################################################################
162 ## LSSerializerImpl
163 #########################################################################*/
166 /**
167 *
168 */
169 bool LSSerializerImpl::write(
170 const Node *nodeArg,
171 const LSOutput &destination)
172 throw (LSException)
173 {
174 outbuf = "";
175 indent = 0;
177 writeNode(nodeArg);
179 //## Check in order specified in the L&S specs
180 LSWriter *writer = destination.getCharacterStream();
181 if (writer)
182 {
183 for (unsigned int i=0 ; i<outbuf.size() ; i++)
184 {
185 int ch = outbuf[i];
186 writer->put(ch);
187 }
188 return true;
189 }
191 LSOutputStream *outputStream = destination.getByteStream();
192 if (outputStream)
193 {
194 for (unsigned int i=0 ; i<outbuf.size() ; i++)
195 {
196 int ch = outbuf[i];
197 writer->put(ch);
198 }
199 return true;
200 }
202 DOMString systemId = destination.getSystemId();
203 if (systemId.size() > 0)
204 {
205 //DO SOMETHING
206 return true;
207 }
209 return false;
210 }
212 /**
213 *
214 */
215 bool LSSerializerImpl::writeToURI(const Node *nodeArg,
216 const DOMString &uriArg)
217 throw(LSException)
218 {
219 outbuf = "";
220 indent = 0;
222 writeNode(nodeArg);
224 DOMString uri = uriArg;
225 char *fileName = (char *) uri.c_str(); //temporary hack
226 FILE *f = fopen(fileName, "rb");
227 if (!f)
228 return false;
229 for (unsigned int i=0 ; i<outbuf.size() ; i++)
230 {
231 int ch = outbuf[i];
232 fputc(ch, f);
233 }
234 fclose(f);
235 return false;
236 }
238 /**
239 *
240 */
241 DOMString LSSerializerImpl::writeToString(const Node *nodeArg)
242 throw(dom::DOMException, LSException)
243 {
244 outbuf = "";
245 indent = 0;
247 writeNode(nodeArg);
248 return outbuf;
249 }
253 //##################
254 //# Non-API methods
255 //##################
258 /**
259 *
260 */
261 void LSSerializerImpl::spaces()
262 {
263 for (int i=0 ; i<indent ; i++)
264 {
265 outbuf.push_back(' ');
266 }
267 }
269 /**
270 *
271 */
272 void LSSerializerImpl::po(char *fmt, ...)
273 {
274 char str[257];
275 va_list args;
276 va_start(args, fmt);
277 vsnprintf(str, 256, fmt, args);
278 va_end(args) ;
280 outbuf.append(str);
281 }
284 void LSSerializerImpl::pos(const DOMString &str)
285 {
286 outbuf.append(str);
287 }
289 void LSSerializerImpl::poxml(const DOMString &str)
290 {
291 for (unsigned int i=0 ; i<str.size() ; i++)
292 {
293 XMLCh ch = (XMLCh) str[i];
294 if (ch == '&')
295 outbuf.append("&r;");
296 else if (ch == '<')
297 outbuf.append("<");
298 else if (ch == '>')
299 outbuf.append(">");
300 else if (ch == '"')
301 outbuf.append(""");
302 else if (ch == '\'')
303 outbuf.append("'");
304 else
305 outbuf.push_back(ch);
306 }
307 }
309 /**
310 *
311 */
312 void LSSerializerImpl::writeNode(const Node *nodeArg)
313 {
314 Node *node = (Node *)nodeArg;
316 int type = node->getNodeType();
318 switch (type)
319 {
321 //#############
322 //# DOCUMENT
323 //#############
324 case Node::DOCUMENT_NODE:
325 {
326 Document *doc = dynamic_cast<Document *>(node);
327 writeNode(doc->getDocumentElement());
328 }
329 break;
331 //#############
332 //# TEXT
333 //#############
334 case Node::TEXT_NODE:
335 {
336 poxml(node->getNodeValue());
337 }
338 break;
341 //#############
342 //# CDATA
343 //#############
344 case Node::CDATA_SECTION_NODE:
345 {
346 pos("<![CDATA[");
347 poxml(node->getNodeValue());
348 pos("]]>");
349 }
350 break;
353 //#############
354 //# ELEMENT
355 //#############
356 case Node::ELEMENT_NODE:
357 {
359 indent+=2;
361 NamedNodeMap attributes = node->getAttributes();
362 int nrAttrs = attributes.getLength();
364 //### Start open tag
365 spaces();
366 po("<");
367 pos(node->getNodeName());
368 //if (nrAttrs>0)
369 // pos(newLine);
371 //### Attributes
372 for (int i=0 ; i<nrAttrs ; i++)
373 {
374 Node *attr = attributes.item(i);
375 spaces();
376 pos(attr->getNodeName());
377 po("=\"");
378 pos(attr->getNodeValue());
379 po("\"");
380 //pos(newLine);
381 }
383 //### Finish open tag
384 //if (nrAttrs>0)
385 // spaces();
386 po(">");
387 //pos(newLine);
389 //### Contents
390 //spaces();
391 pos(node->getNodeValue());
393 //### Children
394 for (Node *child = node->getFirstChild() ;
395 child ;
396 child=child->getNextSibling())
397 {
398 writeNode(child);
399 }
401 //### Close tag
402 //spaces();
403 po("</");
404 pos(node->getNodeName());
405 po(">");
406 pos(newLine);
408 indent-=2;
409 }
410 break;
412 }//switch
414 }
425 } //namespace ls
426 } //namespace dom
427 } //namespace w3c
428 } //namespace org
434 /*#########################################################################
435 ## E N D O F F I L E
436 #########################################################################*/