Code

63257062f381a2f110ee54002138b470fd22540e
[inkscape.git] / src / dom / io / domstream.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 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  * Authors:
36  *   Bob Jamison <rjamison@titan.com>
37  *
38  * Copyright (C) 2004 Inkscape.org
39  *
40  * Released under GNU GPL, read the file 'COPYING' for more information
41  */
43 #include <stdarg.h>
45 #include "domstream.h"
46 #include "charclass.h"
48 namespace org
49 {
50 namespace w3c
51 {
52 namespace dom
53 {
54 namespace io
55 {
58 //#########################################################################
59 //# U T I L I T Y
60 //#########################################################################
62 void pipeStream(InputStream &source, OutputStream &dest)
63 {
64     for (;;)
65         {
66         int ch = source.get();
67         if (ch<0)
68             break;
69         dest.put(ch);
70         }
71     dest.flush();
72 }
74 //#########################################################################
75 //# B A S I C    I N P U T    S T R E A M
76 //#########################################################################
79 /**
80  *
81  */
82 BasicInputStream::BasicInputStream(const InputStream &sourceStream)
83                    : source((InputStream &)sourceStream)
84 {
85     closed = false;
86 }
88 /**
89  * Returns the number of bytes that can be read (or skipped over) from
90  * this input stream without blocking by the next caller of a method for
91  * this input stream.
92  */
93 int BasicInputStream::available()
94 {
95     if (closed)
96         return 0;
97     return source.available();
98 }
101 /**
102  *  Closes this input stream and releases any system resources
103  *  associated with the stream.
104  */
105 void BasicInputStream::close()
107     if (closed)
108         return;
109     source.close();
110     closed = true;
113 /**
114  * Reads the next byte of data from the input stream.  -1 if EOF
115  */
116 int BasicInputStream::get()
118     if (closed)
119         return -1;
120     return source.get();
125 //#########################################################################
126 //# B A S I C    O U T P U T    S T R E A M
127 //#########################################################################
129 /**
130  *
131  */
132 BasicOutputStream::BasicOutputStream(const OutputStream &destinationStream)
133                      : destination((OutputStream &)destinationStream)
135     closed = false;
138 /**
139  * Closes this output stream and releases any system resources
140  * associated with this stream.
141  */
142 void BasicOutputStream::close()
144     if (closed)
145         return;
146     destination.close();
147     closed = true;
150 /**
151  *  Flushes this output stream and forces any buffered output
152  *  bytes to be written out.
153  */
154 void BasicOutputStream::flush()
156     if (closed)
157         return;
158     destination.flush();
161 /**
162  * Writes the specified byte to this output stream.
163  */
164 void BasicOutputStream::put(XMLCh ch)
166     if (closed)
167         return;
168     destination.put(ch);
173 //#########################################################################
174 //# B A S I C    R E A D E R
175 //#########################################################################
178 /**
179  *
180  */
181 BasicReader::BasicReader(Reader &sourceReader)
183     source = &sourceReader;
186 /**
187  * Returns the number of bytes that can be read (or skipped over) from
188  * this reader without blocking by the next caller of a method for
189  * this reader.
190  */
191 int BasicReader::available()
193     if (source)
194         return source->available();
195     else
196         return 0;
200 /**
201  *  Closes this reader and releases any system resources
202  *  associated with the reader.
203  */
204 void BasicReader::close()
206     if (source)
207         source->close();
210 /**
211  * Reads the next byte of data from the reader.
212  */
213 int BasicReader::get()
215     if (source)
216         return source->get();
217     else
218         return -1;
226 /**
227  * Reads a line of data from the reader.
228  */
229 DOMString BasicReader::readLine()
231     DOMString str;
232     while (available() > 0)
233         {
234         XMLCh ch = get();
235         if (ch == '\n')
236             break;
237         str.push_back(ch);
238         }
239     return str;
242 /**
243  * Reads a line of data from the reader.
244  */
245 DOMString BasicReader::readWord()
247     DOMString str;
248     while (available() > 0)
249         {
250         XMLCh ch = get();
251         if (isWhitespace(ch))
252             break;
253         str.push_back(ch);
254         }
255     return str;
259 static bool getLong(DOMString &str, long *val)
261     const char *begin = str.c_str();
262     char *end;
263     long ival = strtol(begin, &end, 10);
264     if (str == end)
265         return false;
266     *val = ival;
267     return true;
270 static bool getULong(const DOMString &str, unsigned long *val)
272     DOMString tmp = str;
273     char *begin = (char *)tmp.c_str();
274     char *end;
275     unsigned long ival = strtoul(begin, &end, 10);
276     if (begin == end)
277         return false;
278     *val = ival;
279     return true;
282 static bool getDouble(const DOMString &str, double *val)
284     DOMString tmp = str;
285     const char *begin = tmp.c_str();
286     char *end;
287     double ival = strtod(begin, &end);
288     if (begin == end)
289         return false;
290     *val = ival;
291     return true;
297 /**
298  *
299  */
300 Reader &BasicReader::readBool (bool& val )
302     DOMString buf = readWord();
303     if (buf == "true")
304         val = true;
305     else
306         val = false;
307     return *this;
310 /**
311  *
312  */
313 Reader &BasicReader::readShort (short& val )
315     DOMString buf = readWord();
316     long ival;
317     if (getLong(buf, &ival))
318         val = (short) ival;
319     return *this;
322 /**
323  *
324  */
325 Reader &BasicReader::readUnsignedShort (unsigned short& val )
327     DOMString buf = readWord();
328     unsigned long ival;
329     if (getULong(buf, &ival))
330         val = (unsigned short) ival;
331     return *this;
334 /**
335  *
336  */
337 Reader &BasicReader::readInt (int& val )
339     DOMString buf = readWord();
340     long ival;
341     if (getLong(buf, &ival))
342         val = (int) ival;
343     return *this;
346 /**
347  *
348  */
349 Reader &BasicReader::readUnsignedInt (unsigned int& val )
351     DOMString buf = readWord();
352     unsigned long ival;
353     if (getULong(buf, &ival))
354         val = (unsigned int) ival;
355     return *this;
358 /**
359  *
360  */
361 Reader &BasicReader::readLong (long& val )
363     DOMString buf = readWord();
364     long ival;
365     if (getLong(buf, &ival))
366         val = ival;
367     return *this;
370 /**
371  *
372  */
373 Reader &BasicReader::readUnsignedLong (unsigned long& val )
375     DOMString buf = readWord();
376     unsigned long ival;
377     if (getULong(buf, &ival))
378         val = ival;
379     return *this;
382 /**
383  *
384  */
385 Reader &BasicReader::readFloat (float& val )
387     DOMString buf = readWord();
388     double ival;
389     if (getDouble(buf, &ival))
390         val = (float)ival;
391     return *this;
394 /**
395  *
396  */
397 Reader &BasicReader::readDouble (double& val )
399     DOMString buf = readWord();
400     double ival;
401     if (getDouble(buf, &ival))
402         val = ival;
403     return *this;
408 //#########################################################################
409 //# I N P U T    S T R E A M    R E A D E R
410 //#########################################################################
413 InputStreamReader::InputStreamReader(const InputStream &inputStreamSource)
414                      : inputStream((InputStream &)inputStreamSource)
420 /**
421  *  Close the underlying OutputStream
422  */
423 void InputStreamReader::close()
425     inputStream.close();
428 /**
429  *  Flush the underlying OutputStream
430  */
431 int InputStreamReader::available()
433     return inputStream.available();
436 /**
437  *  Overloaded to receive its bytes from an InputStream
438  *  rather than a Reader
439  */
440 int InputStreamReader::get()
442     //Do we need conversions here?
443     int ch = (XMLCh)inputStream.get();
444     return ch;
449 //#########################################################################
450 //# S T D    R E A D E R
451 //#########################################################################
454 /**
455  *
456  */
457 StdReader::StdReader()
459     inputStream = new StdInputStream();
462 /**
463  *
464  */
465 StdReader::~StdReader()
467     delete inputStream;
472 /**
473  *  Close the underlying OutputStream
474  */
475 void StdReader::close()
477     inputStream->close();
480 /**
481  *  Flush the underlying OutputStream
482  */
483 int StdReader::available()
485     return inputStream->available();
488 /**
489  *  Overloaded to receive its bytes from an InputStream
490  *  rather than a Reader
491  */
492 int StdReader::get()
494     //Do we need conversions here?
495     XMLCh ch = (XMLCh)inputStream->get();
496     return ch;
503 //#########################################################################
504 //# B A S I C    W R I T E R
505 //#########################################################################
507 /**
508  *
509  */
510 BasicWriter::BasicWriter(const Writer &destinationWriter)
512     destination = (Writer *)&destinationWriter;
515 /**
516  * Closes this writer and releases any system resources
517  * associated with this writer.
518  */
519 void BasicWriter::close()
521     if (destination)
522         destination->close();
525 /**
526  *  Flushes this output stream and forces any buffered output
527  *  bytes to be written out.
528  */
529 void BasicWriter::flush()
531     if (destination)
532         destination->flush();
535 /**
536  * Writes the specified byte to this output writer.
537  */
538 void BasicWriter::put(XMLCh ch)
540     if (destination)
541         destination->put(ch);
544 /**
545  * Provide printf()-like formatting
546  */
547 Writer &BasicWriter::printf(char *fmt, ...)
549     va_list args;
550     va_start(args, fmt);
551     //replace this wish vsnprintf()
552     char buf[256];
553     vsnprintf(buf, 255, fmt, args);
554     va_end(args);
555     if (buf) {
556         writeString(buf);
557         //free(buf);
558     }
559     return *this;
561 /**
562  * Writes the specified character to this output writer.
563  */
564 Writer &BasicWriter::writeChar(char ch)
566     XMLCh uch = ch;
567     put(uch);
568     return *this;
572 /**
573  * Writes the specified standard string to this output writer.
574  */
575 Writer &BasicWriter::writeString(const DOMString &str)
577     for (int i=0; i< (int)str.size(); i++)
578         put(str[i]);
579     return *this;
583 /**
584  *
585  */
586 Writer &BasicWriter::writeBool (bool val )
588     if (val)
589         writeString("true");
590     else
591         writeString("false");
592     return *this;
596 /**
597  *
598  */
599 Writer &BasicWriter::writeShort (short val )
601     char buf[32];
602     snprintf(buf, 31, "%d", val);
603     writeString(buf);
604     return *this;
609 /**
610  *
611  */
612 Writer &BasicWriter::writeUnsignedShort (unsigned short val )
614     char buf[32];
615     snprintf(buf, 31, "%u", val);
616     writeString(buf);
617     return *this;
620 /**
621  *
622  */
623 Writer &BasicWriter::writeInt (int val)
625     char buf[32];
626     snprintf(buf, 31, "%d", val);
627     writeString(buf);
628     return *this;
631 /**
632  *
633  */
634 Writer &BasicWriter::writeUnsignedInt (unsigned int val)
636     char buf[32];
637     snprintf(buf, 31, "%u", val);
638     writeString(buf);
639     return *this;
642 /**
643  *
644  */
645 Writer &BasicWriter::writeLong (long val)
647     char buf[32];
648     snprintf(buf, 31, "%ld", val);
649     writeString(buf);
650     return *this;
653 /**
654  *
655  */
656 Writer &BasicWriter::writeUnsignedLong(unsigned long val)
658     char buf[32];
659     snprintf(buf, 31, "%lu", val);
660     writeString(buf);
661     return *this;
664 /**
665  *
666  */
667 Writer &BasicWriter::writeFloat(float val)
669     char buf[32];
670     snprintf(buf, 31, "%8.3f", val);
671     writeString(buf);
672     return *this;
675 /**
676  *
677  */
678 Writer &BasicWriter::writeDouble(double val)
680     char buf[32];
681     snprintf(buf, 31, "%8.3f", val);
682     writeString(buf);
683     return *this;
689 //#########################################################################
690 //# O U T P U T    S T R E A M    W R I T E R
691 //#########################################################################
694 OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest)
695                      : outputStream(outputStreamDest)
701 /**
702  *  Close the underlying OutputStream
703  */
704 void OutputStreamWriter::close()
706     flush();
707     outputStream.close();
710 /**
711  *  Flush the underlying OutputStream
712  */
713 void OutputStreamWriter::flush()
715       outputStream.flush();
718 /**
719  *  Overloaded to redirect the output chars from the next Writer
720  *  in the chain to an OutputStream instead.
721  */
722 void OutputStreamWriter::put(XMLCh ch)
724     //Do we need conversions here?
725     int intCh = (int) ch;
726     outputStream.put(intCh);
729 //#########################################################################
730 //# S T D    W R I T E R
731 //#########################################################################
734 /**
735  *
736  */
737 StdWriter::StdWriter()
739     outputStream = new StdOutputStream();
743 /**
744  *
745  */
746 StdWriter::~StdWriter()
748     delete outputStream;
753 /**
754  *  Close the underlying OutputStream
755  */
756 void StdWriter::close()
758     flush();
759     outputStream->close();
762 /**
763  *  Flush the underlying OutputStream
764  */
765 void StdWriter::flush()
767       outputStream->flush();
770 /**
771  *  Overloaded to redirect the output chars from the next Writer
772  *  in the chain to an OutputStream instead.
773  */
774 void StdWriter::put(XMLCh ch)
776     //Do we need conversions here?
777     int intCh = (int) ch;
778     outputStream->put(intCh);
792 //###############################################
793 //# O P E R A T O R S
794 //###############################################
795 //# Normally these would be in the .h, but we
796 //# just want to be absolutely certain that these
797 //# are never multiply defined.  Easy to maintain,
798 //# though.  Just occasionally copy/paste these
799 //# into the .h , and replace the {} with a ;
800 //###############################################
805 Reader& operator>> (Reader &reader, bool& val )
806         { return reader.readBool(val); }
808 Reader& operator>> (Reader &reader, short &val)
809         { return reader.readShort(val); }
811 Reader& operator>> (Reader &reader, unsigned short &val)
812         { return reader.readUnsignedShort(val); }
814 Reader& operator>> (Reader &reader, int &val)
815         { return reader.readInt(val); }
817 Reader& operator>> (Reader &reader, unsigned int &val)
818         { return reader.readUnsignedInt(val); }
820 Reader& operator>> (Reader &reader, long &val)
821         { return reader.readLong(val); }
823 Reader& operator>> (Reader &reader, unsigned long &val)
824         { return reader.readUnsignedLong(val); }
826 Reader& operator>> (Reader &reader, float &val)
827         { return reader.readFloat(val); }
829 Reader& operator>> (Reader &reader, double &val)
830         { return reader.readDouble(val); }
835 Writer& operator<< (Writer &writer, char val)
836     { return writer.writeChar(val); }
838 Writer& operator<< (Writer &writer, const DOMString &val)
839     { return writer.writeString(val); }
841 Writer& operator<< (Writer &writer, bool val)
842     { return writer.writeBool(val); }
844 Writer& operator<< (Writer &writer, short val)
845     { return writer.writeShort(val); }
847 Writer& operator<< (Writer &writer, unsigned short val)
848     { return writer.writeUnsignedShort(val); }
850 Writer& operator<< (Writer &writer, int val)
851     { return writer.writeInt(val); }
853 Writer& operator<< (Writer &writer, unsigned int val)
854     { return writer.writeUnsignedInt(val); }
856 Writer& operator<< (Writer &writer, long val)
857     { return writer.writeLong(val); }
859 Writer& operator<< (Writer &writer, unsigned long val)
860     { return writer.writeUnsignedLong(val); }
862 Writer& operator<< (Writer &writer, float val)
863     { return writer.writeFloat(val); }
865 Writer& operator<< (Writer &writer, double val)
866     { return writer.writeDouble(val); }
870 }  //namespace io
871 }  //namespace dom
872 }  //namespace w3c
873 }  //namespace org
876 //#########################################################################
877 //# E N D    O F    F I L E
878 //#########################################################################