Code

fix 1432089: stroke is not drawn not only when it's not set but also when it's too...
[inkscape.git] / src / dom / 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"
47 namespace org
48 {
49 namespace w3c
50 {
51 namespace dom
52 {
55 //#########################################################################
56 //# U T I L I T Y
57 //#########################################################################
59 void pipeStream(InputStream &source, OutputStream &dest)
60 {
61     for (;;)
62         {
63         int ch = source.get();
64         if (ch<0)
65             break;
66         dest.put(ch);
67         }
68     dest.flush();
69 }
71 //#########################################################################
72 //# B A S I C    I N P U T    S T R E A M
73 //#########################################################################
76 /**
77  *
78  */
79 BasicInputStream::BasicInputStream(const InputStream &sourceStream)
80                    : source((InputStream &)sourceStream)
81 {
82     closed = false;
83 }
85 /**
86  * Returns the number of bytes that can be read (or skipped over) from
87  * this input stream without blocking by the next caller of a method for
88  * this input stream.
89  */
90 int BasicInputStream::available()
91 {
92     if (closed)
93         return 0;
94     return source.available();
95 }
98 /**
99  *  Closes this input stream and releases any system resources
100  *  associated with the stream.
101  */
102 void BasicInputStream::close()
104     if (closed)
105         return;
106     source.close();
107     closed = true;
110 /**
111  * Reads the next byte of data from the input stream.  -1 if EOF
112  */
113 int BasicInputStream::get()
115     if (closed)
116         return -1;
117     return source.get();
122 //#########################################################################
123 //# B A S I C    O U T P U T    S T R E A M
124 //#########################################################################
126 /**
127  *
128  */
129 BasicOutputStream::BasicOutputStream(const OutputStream &destinationStream)
130                      : destination((OutputStream &)destinationStream)
132     closed = false;
135 /**
136  * Closes this output stream and releases any system resources
137  * associated with this stream.
138  */
139 void BasicOutputStream::close()
141     if (closed)
142         return;
143     destination.close();
144     closed = true;
147 /**
148  *  Flushes this output stream and forces any buffered output
149  *  bytes to be written out.
150  */
151 void BasicOutputStream::flush()
153     if (closed)
154         return;
155     destination.flush();
158 /**
159  * Writes the specified byte to this output stream.
160  */
161 void BasicOutputStream::put(XMLCh ch)
163     if (closed)
164         return;
165     destination.put(ch);
170 //#########################################################################
171 //# B A S I C    R E A D E R
172 //#########################################################################
175 /**
176  *
177  */
178 BasicReader::BasicReader(Reader &sourceReader)
180     source = &sourceReader;
183 /**
184  * Returns the number of bytes that can be read (or skipped over) from
185  * this reader without blocking by the next caller of a method for
186  * this reader.
187  */
188 int BasicReader::available()
190     if (source)
191         return source->available();
192     else
193         return 0;
197 /**
198  *  Closes this reader and releases any system resources
199  *  associated with the reader.
200  */
201 void BasicReader::close()
203     if (source)
204         source->close();
207 /**
208  * Reads the next byte of data from the reader.
209  */
210 int BasicReader::get()
212     if (source)
213         return source->get();
214     else
215         return -1;
223 /**
224  * Reads a line of data from the reader.
225  */
226 DOMString BasicReader::readLine()
228     DOMString str;
229     while (available() > 0)
230         {
231         XMLCh ch = get();
232         if (ch == '\n')
233             break;
234         str.push_back(ch);
235         }
236     return str;
239 /**
240  * Reads a line of data from the reader.
241  */
242 DOMString BasicReader::readWord()
244     DOMString str;
245     while (available() > 0)
246         {
247         XMLCh ch = get();
248         if (!isprint(ch))
249             break;
250         str.push_back(ch);
251         }
252     return str;
256 static bool getLong(DOMString &str, long *val)
258     const char *begin = str.c_str();
259     char *end;
260     long ival = strtol(begin, &end, 10);
261     if (str == end)
262         return false;
263     *val = ival;
264     return true;
267 static bool getULong(const DOMString &str, unsigned long *val)
269     DOMString tmp = str;
270     char *begin = (char *)tmp.c_str();
271     char *end;
272     unsigned long ival = strtoul(begin, &end, 10);
273     if (begin == end)
274         return false;
275     *val = ival;
276     return true;
279 static bool getDouble(const DOMString &str, double *val)
281     DOMString tmp = str;
282     const char *begin = tmp.c_str();
283     char *end;
284     double ival = strtod(begin, &end);
285     if (begin == end)
286         return false;
287     *val = ival;
288     return true;
294 /**
295  *
296  */
297 Reader &BasicReader::readBool (bool& val )
299     DOMString buf = readWord();
300     if (buf == "true")
301         val = true;
302     else
303         val = false;
304     return *this;
307 /**
308  *
309  */
310 Reader &BasicReader::readShort (short& val )
312     DOMString buf = readWord();
313     long ival;
314     if (getLong(buf, &ival))
315         val = (short) ival;
316     return *this;
319 /**
320  *
321  */
322 Reader &BasicReader::readUnsignedShort (unsigned short& val )
324     DOMString buf = readWord();
325     unsigned long ival;
326     if (getULong(buf, &ival))
327         val = (unsigned short) ival;
328     return *this;
331 /**
332  *
333  */
334 Reader &BasicReader::readInt (int& val )
336     DOMString buf = readWord();
337     long ival;
338     if (getLong(buf, &ival))
339         val = (int) ival;
340     return *this;
343 /**
344  *
345  */
346 Reader &BasicReader::readUnsignedInt (unsigned int& val )
348     DOMString buf = readWord();
349     unsigned long ival;
350     if (getULong(buf, &ival))
351         val = (unsigned int) ival;
352     return *this;
355 /**
356  *
357  */
358 Reader &BasicReader::readLong (long& val )
360     DOMString buf = readWord();
361     long ival;
362     if (getLong(buf, &ival))
363         val = ival;
364     return *this;
367 /**
368  *
369  */
370 Reader &BasicReader::readUnsignedLong (unsigned long& val )
372     DOMString buf = readWord();
373     unsigned long ival;
374     if (getULong(buf, &ival))
375         val = ival;
376     return *this;
379 /**
380  *
381  */
382 Reader &BasicReader::readFloat (float& val )
384     DOMString buf = readWord();
385     double ival;
386     if (getDouble(buf, &ival))
387         val = (float)ival;
388     return *this;
391 /**
392  *
393  */
394 Reader &BasicReader::readDouble (double& val )
396     DOMString buf = readWord();
397     double ival;
398     if (getDouble(buf, &ival))
399         val = ival;
400     return *this;
405 //#########################################################################
406 //# I N P U T    S T R E A M    R E A D E R
407 //#########################################################################
410 InputStreamReader::InputStreamReader(const InputStream &inputStreamSource)
411                      : inputStream((InputStream &)inputStreamSource)
417 /**
418  *  Close the underlying OutputStream
419  */
420 void InputStreamReader::close()
422     inputStream.close();
425 /**
426  *  Flush the underlying OutputStream
427  */
428 int InputStreamReader::available()
430     return inputStream.available();
433 /**
434  *  Overloaded to receive its bytes from an InputStream
435  *  rather than a Reader
436  */
437 int InputStreamReader::get()
439     //Do we need conversions here?
440     int ch = (XMLCh)inputStream.get();
441     return ch;
446 //#########################################################################
447 //# S T D    R E A D E R
448 //#########################################################################
451 /**
452  *
453  */
454 StdReader::StdReader()
456     inputStream = new StdInputStream();
459 /**
460  *
461  */
462 StdReader::~StdReader()
464     delete inputStream;
469 /**
470  *  Close the underlying OutputStream
471  */
472 void StdReader::close()
474     inputStream->close();
477 /**
478  *  Flush the underlying OutputStream
479  */
480 int StdReader::available()
482     return inputStream->available();
485 /**
486  *  Overloaded to receive its bytes from an InputStream
487  *  rather than a Reader
488  */
489 int StdReader::get()
491     //Do we need conversions here?
492     XMLCh ch = (XMLCh)inputStream->get();
493     return ch;
500 //#########################################################################
501 //# B A S I C    W R I T E R
502 //#########################################################################
504 /**
505  *
506  */
507 BasicWriter::BasicWriter(const Writer &destinationWriter)
509     destination = (Writer *)&destinationWriter;
512 /**
513  * Closes this writer and releases any system resources
514  * associated with this writer.
515  */
516 void BasicWriter::close()
518     if (destination)
519         destination->close();
522 /**
523  *  Flushes this output stream and forces any buffered output
524  *  bytes to be written out.
525  */
526 void BasicWriter::flush()
528     if (destination)
529         destination->flush();
532 /**
533  * Writes the specified byte to this output writer.
534  */
535 void BasicWriter::put(XMLCh ch)
537     if (destination)
538         destination->put(ch);
541 /**
542  * Provide printf()-like formatting
543  */
544 Writer &BasicWriter::printf(char *fmt, ...)
546     va_list args;
547     va_start(args, fmt);
548     //replace this wish vsnprintf()
549     char buf[256];
550     vsnprintf(buf, 255, fmt, args);
551     va_end(args);
552     if (buf) {
553         writeString(buf);
554         //free(buf);
555     }
556     return *this;
558 /**
559  * Writes the specified character to this output writer.
560  */
561 Writer &BasicWriter::writeChar(char ch)
563     XMLCh uch = ch;
564     put(uch);
565     return *this;
569 /**
570  * Writes the specified standard string to this output writer.
571  */
572 Writer &BasicWriter::writeString(const DOMString &str)
574     for (int i=0; i< (int)str.size(); i++)
575         put(str[i]);
576     return *this;
580 /**
581  *
582  */
583 Writer &BasicWriter::writeBool (bool val )
585     if (val)
586         writeString("true");
587     else
588         writeString("false");
589     return *this;
593 /**
594  *
595  */
596 Writer &BasicWriter::writeShort (short val )
598     char buf[32];
599     snprintf(buf, 31, "%d", val);
600     writeString(buf);
601     return *this;
606 /**
607  *
608  */
609 Writer &BasicWriter::writeUnsignedShort (unsigned short val )
611     char buf[32];
612     snprintf(buf, 31, "%u", val);
613     writeString(buf);
614     return *this;
617 /**
618  *
619  */
620 Writer &BasicWriter::writeInt (int val)
622     char buf[32];
623     snprintf(buf, 31, "%d", val);
624     writeString(buf);
625     return *this;
628 /**
629  *
630  */
631 Writer &BasicWriter::writeUnsignedInt (unsigned int val)
633     char buf[32];
634     snprintf(buf, 31, "%u", val);
635     writeString(buf);
636     return *this;
639 /**
640  *
641  */
642 Writer &BasicWriter::writeLong (long val)
644     char buf[32];
645     snprintf(buf, 31, "%ld", val);
646     writeString(buf);
647     return *this;
650 /**
651  *
652  */
653 Writer &BasicWriter::writeUnsignedLong(unsigned long val)
655     char buf[32];
656     snprintf(buf, 31, "%lu", val);
657     writeString(buf);
658     return *this;
661 /**
662  *
663  */
664 Writer &BasicWriter::writeFloat(float val)
666     char buf[32];
667     snprintf(buf, 31, "%8.3f", val);
668     writeString(buf);
669     return *this;
672 /**
673  *
674  */
675 Writer &BasicWriter::writeDouble(double val)
677     char buf[32];
678     snprintf(buf, 31, "%8.3f", val);
679     writeString(buf);
680     return *this;
686 //#########################################################################
687 //# O U T P U T    S T R E A M    W R I T E R
688 //#########################################################################
691 OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest)
692                      : outputStream(outputStreamDest)
698 /**
699  *  Close the underlying OutputStream
700  */
701 void OutputStreamWriter::close()
703     flush();
704     outputStream.close();
707 /**
708  *  Flush the underlying OutputStream
709  */
710 void OutputStreamWriter::flush()
712       outputStream.flush();
715 /**
716  *  Overloaded to redirect the output chars from the next Writer
717  *  in the chain to an OutputStream instead.
718  */
719 void OutputStreamWriter::put(XMLCh ch)
721     //Do we need conversions here?
722     int intCh = (int) ch;
723     outputStream.put(intCh);
726 //#########################################################################
727 //# S T D    W R I T E R
728 //#########################################################################
731 /**
732  *
733  */
734 StdWriter::StdWriter()
736     outputStream = new StdOutputStream();
740 /**
741  *
742  */
743 StdWriter::~StdWriter()
745     delete outputStream;
750 /**
751  *  Close the underlying OutputStream
752  */
753 void StdWriter::close()
755     flush();
756     outputStream->close();
759 /**
760  *  Flush the underlying OutputStream
761  */
762 void StdWriter::flush()
764       outputStream->flush();
767 /**
768  *  Overloaded to redirect the output chars from the next Writer
769  *  in the chain to an OutputStream instead.
770  */
771 void StdWriter::put(XMLCh ch)
773     //Do we need conversions here?
774     int intCh = (int) ch;
775     outputStream->put(intCh);
789 //###############################################
790 //# O P E R A T O R S
791 //###############################################
792 //# Normally these would be in the .h, but we
793 //# just want to be absolutely certain that these
794 //# are never multiply defined.  Easy to maintain,
795 //# though.  Just occasionally copy/paste these
796 //# into the .h , and replace the {} with a ;
797 //###############################################
802 Reader& operator>> (Reader &reader, bool& val )
803         { return reader.readBool(val); }
805 Reader& operator>> (Reader &reader, short &val)
806         { return reader.readShort(val); }
808 Reader& operator>> (Reader &reader, unsigned short &val)
809         { return reader.readUnsignedShort(val); }
811 Reader& operator>> (Reader &reader, int &val)
812         { return reader.readInt(val); }
814 Reader& operator>> (Reader &reader, unsigned int &val)
815         { return reader.readUnsignedInt(val); }
817 Reader& operator>> (Reader &reader, long &val)
818         { return reader.readLong(val); }
820 Reader& operator>> (Reader &reader, unsigned long &val)
821         { return reader.readUnsignedLong(val); }
823 Reader& operator>> (Reader &reader, float &val)
824         { return reader.readFloat(val); }
826 Reader& operator>> (Reader &reader, double &val)
827         { return reader.readDouble(val); }
832 Writer& operator<< (Writer &writer, char val)
833     { return writer.writeChar(val); }
835 Writer& operator<< (Writer &writer, const DOMString &val)
836     { return writer.writeString(val); }
838 Writer& operator<< (Writer &writer, bool val)
839     { return writer.writeBool(val); }
841 Writer& operator<< (Writer &writer, short val)
842     { return writer.writeShort(val); }
844 Writer& operator<< (Writer &writer, unsigned short val)
845     { return writer.writeUnsignedShort(val); }
847 Writer& operator<< (Writer &writer, int val)
848     { return writer.writeInt(val); }
850 Writer& operator<< (Writer &writer, unsigned int val)
851     { return writer.writeUnsignedInt(val); }
853 Writer& operator<< (Writer &writer, long val)
854     { return writer.writeLong(val); }
856 Writer& operator<< (Writer &writer, unsigned long val)
857     { return writer.writeUnsignedLong(val); }
859 Writer& operator<< (Writer &writer, float val)
860     { return writer.writeFloat(val); }
862 Writer& operator<< (Writer &writer, double val)
863     { return writer.writeDouble(val); }
867 }  //namespace dom
868 }  //namespace w3c
869 }  //namespace org
872 //#########################################################################
873 //# E N D    O F    F I L E
874 //#########################################################################