3ffba53feefab4f27719624cd18b41b7f6b0425f
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) 2006 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 /**
31 * Our base input/output stream classes. These are is directly
32 * inherited from iostreams, and includes any extra
33 * functionality that we might need.
34 *
35 */
37 #include <stdarg.h>
39 #include "domstream.h"
40 #include "dom/charclass.h"
42 namespace org
43 {
44 namespace w3c
45 {
46 namespace dom
47 {
48 namespace io
49 {
52 //#########################################################################
53 //# U T I L I T Y
54 //#########################################################################
56 void pipeStream(InputStream &source, OutputStream &dest)
57 {
58 for (;;)
59 {
60 int ch = source.get();
61 if (ch<0)
62 break;
63 dest.put(ch);
64 }
65 dest.flush();
66 }
68 //#########################################################################
69 //# B A S I C I N P U T S T R E A M
70 //#########################################################################
73 /**
74 *
75 */
76 BasicInputStream::BasicInputStream(const InputStream &sourceStream)
77 : source((InputStream &)sourceStream)
78 {
79 closed = false;
80 }
82 /**
83 * Returns the number of bytes that can be read (or skipped over) from
84 * this input stream without blocking by the next caller of a method for
85 * this input stream.
86 */
87 int BasicInputStream::available()
88 {
89 if (closed)
90 return 0;
91 return source.available();
92 }
95 /**
96 * Closes this input stream and releases any system resources
97 * associated with the stream.
98 */
99 void BasicInputStream::close()
100 {
101 if (closed)
102 return;
103 source.close();
104 closed = true;
105 }
107 /**
108 * Reads the next byte of data from the input stream. -1 if EOF
109 */
110 int BasicInputStream::get()
111 {
112 if (closed)
113 return -1;
114 return source.get();
115 }
119 //#########################################################################
120 //# B A S I C O U T P U T S T R E A M
121 //#########################################################################
123 /**
124 *
125 */
126 BasicOutputStream::BasicOutputStream(const OutputStream &destinationStream)
127 : destination((OutputStream &)destinationStream)
128 {
129 closed = false;
130 }
132 /**
133 * Closes this output stream and releases any system resources
134 * associated with this stream.
135 */
136 void BasicOutputStream::close()
137 {
138 if (closed)
139 return;
140 destination.close();
141 closed = true;
142 }
144 /**
145 * Flushes this output stream and forces any buffered output
146 * bytes to be written out.
147 */
148 void BasicOutputStream::flush()
149 {
150 if (closed)
151 return;
152 destination.flush();
153 }
155 /**
156 * Writes the specified byte to this output stream.
157 */
158 void BasicOutputStream::put(XMLCh ch)
159 {
160 if (closed)
161 return;
162 destination.put(ch);
163 }
167 //#########################################################################
168 //# B A S I C R E A D E R
169 //#########################################################################
172 /**
173 *
174 */
175 BasicReader::BasicReader(Reader &sourceReader)
176 {
177 source = &sourceReader;
178 }
180 /**
181 * Returns the number of bytes that can be read (or skipped over) from
182 * this reader without blocking by the next caller of a method for
183 * this reader.
184 */
185 int BasicReader::available()
186 {
187 if (source)
188 return source->available();
189 else
190 return 0;
191 }
194 /**
195 * Closes this reader and releases any system resources
196 * associated with the reader.
197 */
198 void BasicReader::close()
199 {
200 if (source)
201 source->close();
202 }
204 /**
205 * Reads the next byte of data from the reader.
206 */
207 int BasicReader::get()
208 {
209 if (source)
210 return source->get();
211 else
212 return -1;
213 }
220 /**
221 * Reads a line of data from the reader.
222 */
223 DOMString BasicReader::readLine()
224 {
225 DOMString str;
226 while (available() > 0)
227 {
228 XMLCh ch = get();
229 if (ch == '\n')
230 break;
231 str.push_back(ch);
232 }
233 return str;
234 }
236 /**
237 * Reads a line of data from the reader.
238 */
239 DOMString BasicReader::readWord()
240 {
241 DOMString str;
242 while (available() > 0)
243 {
244 XMLCh ch = get();
245 if (isWhitespace(ch))
246 break;
247 str.push_back(ch);
248 }
249 return str;
250 }
253 static bool getLong(DOMString &str, long *val)
254 {
255 const char *begin = str.c_str();
256 char *end;
257 long ival = strtol(begin, &end, 10);
258 if (str == end)
259 return false;
260 *val = ival;
261 return true;
262 }
264 static bool getULong(const DOMString &str, unsigned long *val)
265 {
266 DOMString tmp = str;
267 char *begin = (char *)tmp.c_str();
268 char *end;
269 unsigned long ival = strtoul(begin, &end, 10);
270 if (begin == end)
271 return false;
272 *val = ival;
273 return true;
274 }
276 static bool getDouble(const DOMString &str, double *val)
277 {
278 DOMString tmp = str;
279 const char *begin = tmp.c_str();
280 char *end;
281 double ival = strtod(begin, &end);
282 if (begin == end)
283 return false;
284 *val = ival;
285 return true;
286 }
291 /**
292 *
293 */
294 Reader &BasicReader::readBool (bool& val )
295 {
296 DOMString buf = readWord();
297 if (buf == "true")
298 val = true;
299 else
300 val = false;
301 return *this;
302 }
304 /**
305 *
306 */
307 Reader &BasicReader::readShort (short& val )
308 {
309 DOMString buf = readWord();
310 long ival;
311 if (getLong(buf, &ival))
312 val = (short) ival;
313 return *this;
314 }
316 /**
317 *
318 */
319 Reader &BasicReader::readUnsignedShort (unsigned short& val )
320 {
321 DOMString buf = readWord();
322 unsigned long ival;
323 if (getULong(buf, &ival))
324 val = (unsigned short) ival;
325 return *this;
326 }
328 /**
329 *
330 */
331 Reader &BasicReader::readInt (int& val )
332 {
333 DOMString buf = readWord();
334 long ival;
335 if (getLong(buf, &ival))
336 val = (int) ival;
337 return *this;
338 }
340 /**
341 *
342 */
343 Reader &BasicReader::readUnsignedInt (unsigned int& val )
344 {
345 DOMString buf = readWord();
346 unsigned long ival;
347 if (getULong(buf, &ival))
348 val = (unsigned int) ival;
349 return *this;
350 }
352 /**
353 *
354 */
355 Reader &BasicReader::readLong (long& val )
356 {
357 DOMString buf = readWord();
358 long ival;
359 if (getLong(buf, &ival))
360 val = ival;
361 return *this;
362 }
364 /**
365 *
366 */
367 Reader &BasicReader::readUnsignedLong (unsigned long& val )
368 {
369 DOMString buf = readWord();
370 unsigned long ival;
371 if (getULong(buf, &ival))
372 val = ival;
373 return *this;
374 }
376 /**
377 *
378 */
379 Reader &BasicReader::readFloat (float& val )
380 {
381 DOMString buf = readWord();
382 double ival;
383 if (getDouble(buf, &ival))
384 val = (float)ival;
385 return *this;
386 }
388 /**
389 *
390 */
391 Reader &BasicReader::readDouble (double& val )
392 {
393 DOMString buf = readWord();
394 double ival;
395 if (getDouble(buf, &ival))
396 val = ival;
397 return *this;
398 }
402 //#########################################################################
403 //# I N P U T S T R E A M R E A D E R
404 //#########################################################################
407 InputStreamReader::InputStreamReader(const InputStream &inputStreamSource)
408 : inputStream((InputStream &)inputStreamSource)
409 {
410 }
414 /**
415 * Close the underlying OutputStream
416 */
417 void InputStreamReader::close()
418 {
419 inputStream.close();
420 }
422 /**
423 * Flush the underlying OutputStream
424 */
425 int InputStreamReader::available()
426 {
427 return inputStream.available();
428 }
430 /**
431 * Overloaded to receive its bytes from an InputStream
432 * rather than a Reader
433 */
434 int InputStreamReader::get()
435 {
436 //Do we need conversions here?
437 int ch = (XMLCh)inputStream.get();
438 return ch;
439 }
443 //#########################################################################
444 //# S T D R E A D E R
445 //#########################################################################
448 /**
449 *
450 */
451 StdReader::StdReader()
452 {
453 inputStream = new StdInputStream();
454 }
456 /**
457 *
458 */
459 StdReader::~StdReader()
460 {
461 delete inputStream;
462 }
466 /**
467 * Close the underlying OutputStream
468 */
469 void StdReader::close()
470 {
471 inputStream->close();
472 }
474 /**
475 * Flush the underlying OutputStream
476 */
477 int StdReader::available()
478 {
479 return inputStream->available();
480 }
482 /**
483 * Overloaded to receive its bytes from an InputStream
484 * rather than a Reader
485 */
486 int StdReader::get()
487 {
488 //Do we need conversions here?
489 XMLCh ch = (XMLCh)inputStream->get();
490 return ch;
491 }
497 //#########################################################################
498 //# B A S I C W R I T E R
499 //#########################################################################
501 /**
502 *
503 */
504 BasicWriter::BasicWriter(const Writer &destinationWriter)
505 {
506 destination = (Writer *)&destinationWriter;
507 }
509 /**
510 * Closes this writer and releases any system resources
511 * associated with this writer.
512 */
513 void BasicWriter::close()
514 {
515 if (destination)
516 destination->close();
517 }
519 /**
520 * Flushes this output stream and forces any buffered output
521 * bytes to be written out.
522 */
523 void BasicWriter::flush()
524 {
525 if (destination)
526 destination->flush();
527 }
529 /**
530 * Writes the specified byte to this output writer.
531 */
532 void BasicWriter::put(XMLCh ch)
533 {
534 if (destination)
535 destination->put(ch);
536 }
538 /**
539 * Provide printf()-like formatting
540 */
541 Writer &BasicWriter::printf(char *fmt, ...)
542 {
543 va_list args;
544 va_start(args, fmt);
545 //replace this wish vsnprintf()
546 vsnprintf(formatBuf, 2047, fmt, args);
547 va_end(args);
548 writeString(formatBuf);
550 return *this;
551 }
552 /**
553 * Writes the specified character to this output writer.
554 */
555 Writer &BasicWriter::writeChar(char ch)
556 {
557 XMLCh uch = ch;
558 put(uch);
559 return *this;
560 }
563 /**
564 * Writes the specified standard string to this output writer.
565 */
566 Writer &BasicWriter::writeString(const DOMString &str)
567 {
568 for (int i=0; i< (int)str.size(); i++)
569 put(str[i]);
570 return *this;
571 }
574 /**
575 *
576 */
577 Writer &BasicWriter::writeBool (bool val )
578 {
579 if (val)
580 writeString("true");
581 else
582 writeString("false");
583 return *this;
584 }
587 /**
588 *
589 */
590 Writer &BasicWriter::writeShort (short val )
591 {
592 char buf[32];
593 snprintf(buf, 31, "%d", val);
594 writeString(buf);
595 return *this;
596 }
600 /**
601 *
602 */
603 Writer &BasicWriter::writeUnsignedShort (unsigned short val )
604 {
605 char buf[32];
606 snprintf(buf, 31, "%u", val);
607 writeString(buf);
608 return *this;
609 }
611 /**
612 *
613 */
614 Writer &BasicWriter::writeInt (int val)
615 {
616 char buf[32];
617 snprintf(buf, 31, "%d", val);
618 writeString(buf);
619 return *this;
620 }
622 /**
623 *
624 */
625 Writer &BasicWriter::writeUnsignedInt (unsigned int val)
626 {
627 char buf[32];
628 snprintf(buf, 31, "%u", val);
629 writeString(buf);
630 return *this;
631 }
633 /**
634 *
635 */
636 Writer &BasicWriter::writeLong (long val)
637 {
638 char buf[32];
639 snprintf(buf, 31, "%ld", val);
640 writeString(buf);
641 return *this;
642 }
644 /**
645 *
646 */
647 Writer &BasicWriter::writeUnsignedLong(unsigned long val)
648 {
649 char buf[32];
650 snprintf(buf, 31, "%lu", val);
651 writeString(buf);
652 return *this;
653 }
655 /**
656 *
657 */
658 Writer &BasicWriter::writeFloat(float val)
659 {
660 char buf[32];
661 snprintf(buf, 31, "%8.3f", val);
662 writeString(buf);
663 return *this;
664 }
666 /**
667 *
668 */
669 Writer &BasicWriter::writeDouble(double val)
670 {
671 char buf[32];
672 snprintf(buf, 31, "%8.3f", val);
673 writeString(buf);
674 return *this;
675 }
680 //#########################################################################
681 //# O U T P U T S T R E A M W R I T E R
682 //#########################################################################
685 OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest)
686 : outputStream(outputStreamDest)
687 {
688 }
692 /**
693 * Close the underlying OutputStream
694 */
695 void OutputStreamWriter::close()
696 {
697 flush();
698 outputStream.close();
699 }
701 /**
702 * Flush the underlying OutputStream
703 */
704 void OutputStreamWriter::flush()
705 {
706 outputStream.flush();
707 }
709 /**
710 * Overloaded to redirect the output chars from the next Writer
711 * in the chain to an OutputStream instead.
712 */
713 void OutputStreamWriter::put(XMLCh ch)
714 {
715 //Do we need conversions here?
716 int intCh = (int) ch;
717 outputStream.put(intCh);
718 }
720 //#########################################################################
721 //# S T D W R I T E R
722 //#########################################################################
725 /**
726 *
727 */
728 StdWriter::StdWriter()
729 {
730 outputStream = new StdOutputStream();
731 }
734 /**
735 *
736 */
737 StdWriter::~StdWriter()
738 {
739 delete outputStream;
740 }
744 /**
745 * Close the underlying OutputStream
746 */
747 void StdWriter::close()
748 {
749 flush();
750 outputStream->close();
751 }
753 /**
754 * Flush the underlying OutputStream
755 */
756 void StdWriter::flush()
757 {
758 outputStream->flush();
759 }
761 /**
762 * Overloaded to redirect the output chars from the next Writer
763 * in the chain to an OutputStream instead.
764 */
765 void StdWriter::put(XMLCh ch)
766 {
767 //Do we need conversions here?
768 int intCh = (int) ch;
769 outputStream->put(intCh);
770 }
783 //###############################################
784 //# O P E R A T O R S
785 //###############################################
786 //# Normally these would be in the .h, but we
787 //# just want to be absolutely certain that these
788 //# are never multiply defined. Easy to maintain,
789 //# though. Just occasionally copy/paste these
790 //# into the .h , and replace the {} with a ;
791 //###############################################
796 Reader& operator>> (Reader &reader, bool& val )
797 { return reader.readBool(val); }
799 Reader& operator>> (Reader &reader, short &val)
800 { return reader.readShort(val); }
802 Reader& operator>> (Reader &reader, unsigned short &val)
803 { return reader.readUnsignedShort(val); }
805 Reader& operator>> (Reader &reader, int &val)
806 { return reader.readInt(val); }
808 Reader& operator>> (Reader &reader, unsigned int &val)
809 { return reader.readUnsignedInt(val); }
811 Reader& operator>> (Reader &reader, long &val)
812 { return reader.readLong(val); }
814 Reader& operator>> (Reader &reader, unsigned long &val)
815 { return reader.readUnsignedLong(val); }
817 Reader& operator>> (Reader &reader, float &val)
818 { return reader.readFloat(val); }
820 Reader& operator>> (Reader &reader, double &val)
821 { return reader.readDouble(val); }
826 Writer& operator<< (Writer &writer, char val)
827 { return writer.writeChar(val); }
829 Writer& operator<< (Writer &writer, const DOMString &val)
830 { return writer.writeString(val); }
832 Writer& operator<< (Writer &writer, bool val)
833 { return writer.writeBool(val); }
835 Writer& operator<< (Writer &writer, short val)
836 { return writer.writeShort(val); }
838 Writer& operator<< (Writer &writer, unsigned short val)
839 { return writer.writeUnsignedShort(val); }
841 Writer& operator<< (Writer &writer, int val)
842 { return writer.writeInt(val); }
844 Writer& operator<< (Writer &writer, unsigned int val)
845 { return writer.writeUnsignedInt(val); }
847 Writer& operator<< (Writer &writer, long val)
848 { return writer.writeLong(val); }
850 Writer& operator<< (Writer &writer, unsigned long val)
851 { return writer.writeUnsignedLong(val); }
853 Writer& operator<< (Writer &writer, float val)
854 { return writer.writeFloat(val); }
856 Writer& operator<< (Writer &writer, double val)
857 { return writer.writeDouble(val); }
861 } //namespace io
862 } //namespace dom
863 } //namespace w3c
864 } //namespace org
867 //#########################################################################
868 //# E N D O F F I L E
869 //#########################################################################