Code

Made the format buffer larger and part of the class, not the stack.
[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) 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()
101     if (closed)
102         return;
103     source.close();
104     closed = true;
107 /**
108  * Reads the next byte of data from the input stream.  -1 if EOF
109  */
110 int BasicInputStream::get()
112     if (closed)
113         return -1;
114     return source.get();
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)
129     closed = false;
132 /**
133  * Closes this output stream and releases any system resources
134  * associated with this stream.
135  */
136 void BasicOutputStream::close()
138     if (closed)
139         return;
140     destination.close();
141     closed = true;
144 /**
145  *  Flushes this output stream and forces any buffered output
146  *  bytes to be written out.
147  */
148 void BasicOutputStream::flush()
150     if (closed)
151         return;
152     destination.flush();
155 /**
156  * Writes the specified byte to this output stream.
157  */
158 void BasicOutputStream::put(XMLCh ch)
160     if (closed)
161         return;
162     destination.put(ch);
167 //#########################################################################
168 //# B A S I C    R E A D E R
169 //#########################################################################
172 /**
173  *
174  */
175 BasicReader::BasicReader(Reader &sourceReader)
177     source = &sourceReader;
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()
187     if (source)
188         return source->available();
189     else
190         return 0;
194 /**
195  *  Closes this reader and releases any system resources
196  *  associated with the reader.
197  */
198 void BasicReader::close()
200     if (source)
201         source->close();
204 /**
205  * Reads the next byte of data from the reader.
206  */
207 int BasicReader::get()
209     if (source)
210         return source->get();
211     else
212         return -1;
220 /**
221  * Reads a line of data from the reader.
222  */
223 DOMString BasicReader::readLine()
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;
236 /**
237  * Reads a line of data from the reader.
238  */
239 DOMString BasicReader::readWord()
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;
253 static bool getLong(DOMString &str, long *val)
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;
264 static bool getULong(const DOMString &str, unsigned long *val)
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;
276 static bool getDouble(const DOMString &str, double *val)
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;
291 /**
292  *
293  */
294 Reader &BasicReader::readBool (bool& val )
296     DOMString buf = readWord();
297     if (buf == "true")
298         val = true;
299     else
300         val = false;
301     return *this;
304 /**
305  *
306  */
307 Reader &BasicReader::readShort (short& val )
309     DOMString buf = readWord();
310     long ival;
311     if (getLong(buf, &ival))
312         val = (short) ival;
313     return *this;
316 /**
317  *
318  */
319 Reader &BasicReader::readUnsignedShort (unsigned short& val )
321     DOMString buf = readWord();
322     unsigned long ival;
323     if (getULong(buf, &ival))
324         val = (unsigned short) ival;
325     return *this;
328 /**
329  *
330  */
331 Reader &BasicReader::readInt (int& val )
333     DOMString buf = readWord();
334     long ival;
335     if (getLong(buf, &ival))
336         val = (int) ival;
337     return *this;
340 /**
341  *
342  */
343 Reader &BasicReader::readUnsignedInt (unsigned int& val )
345     DOMString buf = readWord();
346     unsigned long ival;
347     if (getULong(buf, &ival))
348         val = (unsigned int) ival;
349     return *this;
352 /**
353  *
354  */
355 Reader &BasicReader::readLong (long& val )
357     DOMString buf = readWord();
358     long ival;
359     if (getLong(buf, &ival))
360         val = ival;
361     return *this;
364 /**
365  *
366  */
367 Reader &BasicReader::readUnsignedLong (unsigned long& val )
369     DOMString buf = readWord();
370     unsigned long ival;
371     if (getULong(buf, &ival))
372         val = ival;
373     return *this;
376 /**
377  *
378  */
379 Reader &BasicReader::readFloat (float& val )
381     DOMString buf = readWord();
382     double ival;
383     if (getDouble(buf, &ival))
384         val = (float)ival;
385     return *this;
388 /**
389  *
390  */
391 Reader &BasicReader::readDouble (double& val )
393     DOMString buf = readWord();
394     double ival;
395     if (getDouble(buf, &ival))
396         val = ival;
397     return *this;
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)
414 /**
415  *  Close the underlying OutputStream
416  */
417 void InputStreamReader::close()
419     inputStream.close();
422 /**
423  *  Flush the underlying OutputStream
424  */
425 int InputStreamReader::available()
427     return inputStream.available();
430 /**
431  *  Overloaded to receive its bytes from an InputStream
432  *  rather than a Reader
433  */
434 int InputStreamReader::get()
436     //Do we need conversions here?
437     int ch = (XMLCh)inputStream.get();
438     return ch;
443 //#########################################################################
444 //# S T D    R E A D E R
445 //#########################################################################
448 /**
449  *
450  */
451 StdReader::StdReader()
453     inputStream = new StdInputStream();
456 /**
457  *
458  */
459 StdReader::~StdReader()
461     delete inputStream;
466 /**
467  *  Close the underlying OutputStream
468  */
469 void StdReader::close()
471     inputStream->close();
474 /**
475  *  Flush the underlying OutputStream
476  */
477 int StdReader::available()
479     return inputStream->available();
482 /**
483  *  Overloaded to receive its bytes from an InputStream
484  *  rather than a Reader
485  */
486 int StdReader::get()
488     //Do we need conversions here?
489     XMLCh ch = (XMLCh)inputStream->get();
490     return ch;
497 //#########################################################################
498 //# B A S I C    W R I T E R
499 //#########################################################################
501 /**
502  *
503  */
504 BasicWriter::BasicWriter(const Writer &destinationWriter)
506     destination = (Writer *)&destinationWriter;
509 /**
510  * Closes this writer and releases any system resources
511  * associated with this writer.
512  */
513 void BasicWriter::close()
515     if (destination)
516         destination->close();
519 /**
520  *  Flushes this output stream and forces any buffered output
521  *  bytes to be written out.
522  */
523 void BasicWriter::flush()
525     if (destination)
526         destination->flush();
529 /**
530  * Writes the specified byte to this output writer.
531  */
532 void BasicWriter::put(XMLCh ch)
534     if (destination)
535         destination->put(ch);
538 /**
539  * Provide printf()-like formatting
540  */
541 Writer &BasicWriter::printf(char *fmt, ...)
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;
552 /**
553  * Writes the specified character to this output writer.
554  */
555 Writer &BasicWriter::writeChar(char ch)
557     XMLCh uch = ch;
558     put(uch);
559     return *this;
563 /**
564  * Writes the specified standard string to this output writer.
565  */
566 Writer &BasicWriter::writeString(const DOMString &str)
568     for (int i=0; i< (int)str.size(); i++)
569         put(str[i]);
570     return *this;
574 /**
575  *
576  */
577 Writer &BasicWriter::writeBool (bool val )
579     if (val)
580         writeString("true");
581     else
582         writeString("false");
583     return *this;
587 /**
588  *
589  */
590 Writer &BasicWriter::writeShort (short val )
592     char buf[32];
593     snprintf(buf, 31, "%d", val);
594     writeString(buf);
595     return *this;
600 /**
601  *
602  */
603 Writer &BasicWriter::writeUnsignedShort (unsigned short val )
605     char buf[32];
606     snprintf(buf, 31, "%u", val);
607     writeString(buf);
608     return *this;
611 /**
612  *
613  */
614 Writer &BasicWriter::writeInt (int val)
616     char buf[32];
617     snprintf(buf, 31, "%d", val);
618     writeString(buf);
619     return *this;
622 /**
623  *
624  */
625 Writer &BasicWriter::writeUnsignedInt (unsigned int val)
627     char buf[32];
628     snprintf(buf, 31, "%u", val);
629     writeString(buf);
630     return *this;
633 /**
634  *
635  */
636 Writer &BasicWriter::writeLong (long val)
638     char buf[32];
639     snprintf(buf, 31, "%ld", val);
640     writeString(buf);
641     return *this;
644 /**
645  *
646  */
647 Writer &BasicWriter::writeUnsignedLong(unsigned long val)
649     char buf[32];
650     snprintf(buf, 31, "%lu", val);
651     writeString(buf);
652     return *this;
655 /**
656  *
657  */
658 Writer &BasicWriter::writeFloat(float val)
660     char buf[32];
661     snprintf(buf, 31, "%8.3f", val);
662     writeString(buf);
663     return *this;
666 /**
667  *
668  */
669 Writer &BasicWriter::writeDouble(double val)
671     char buf[32];
672     snprintf(buf, 31, "%8.3f", val);
673     writeString(buf);
674     return *this;
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)
692 /**
693  *  Close the underlying OutputStream
694  */
695 void OutputStreamWriter::close()
697     flush();
698     outputStream.close();
701 /**
702  *  Flush the underlying OutputStream
703  */
704 void OutputStreamWriter::flush()
706       outputStream.flush();
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)
715     //Do we need conversions here?
716     int intCh = (int) ch;
717     outputStream.put(intCh);
720 //#########################################################################
721 //# S T D    W R I T E R
722 //#########################################################################
725 /**
726  *
727  */
728 StdWriter::StdWriter()
730     outputStream = new StdOutputStream();
734 /**
735  *
736  */
737 StdWriter::~StdWriter()
739     delete outputStream;
744 /**
745  *  Close the underlying OutputStream
746  */
747 void StdWriter::close()
749     flush();
750     outputStream->close();
753 /**
754  *  Flush the underlying OutputStream
755  */
756 void StdWriter::flush()
758       outputStream->flush();
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)
767     //Do we need conversions here?
768     int intCh = (int) ch;
769     outputStream->put(intCh);
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 //#########################################################################