Code

updated spanish.nsh and inkscape.nsi to reflect latest file-changes
[inkscape.git] / trunk / 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-2008 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 <math.h>
38 #include <stdarg.h>
40 #include "domstream.h"
41 #include "dom/ucd.h"
43 namespace org
44 {
45 namespace w3c
46 {
47 namespace dom
48 {
49 namespace io
50 {
53 //#########################################################################
54 //# U T I L I T Y
55 //#########################################################################
57 void pipeStream(InputStream &source, OutputStream &dest)
58 {
59     for (;;)
60         {
61         int ch = source.get();
62         if (ch<0)
63             break;
64         dest.put(ch);
65         }
66     dest.flush();
67 }
71 //#########################################################################
72 //# F O R M A T T E D    P R I N T I N G
73 //#########################################################################
75 static char const *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
77 static int dprintInt(Writer &outs,
78                      long arg, int base,
79                      int flag, int width, int /*precision*/)
80 {
82     DOMString buf;
84     //### Get the digits
85     while (arg > 0)
86         {
87         int ch = arg % base;
88         buf.insert(buf.begin(), digits[ch]);        
89         arg /= base;        
90         }
92     if (flag == '#' && base == 16)
93         {
94         buf.insert(buf.begin(), 'x');
95         buf.insert(buf.begin(), '0');
96         }
98     if (buf.size() == 0)
99         buf = "0";
101     int pad = width - (int)buf.size();
102     for (int i=0 ; i<pad ; i++)
103         buf.insert(buf.begin(), '0');
105     //### Output the result
106     for (unsigned int i=0 ; i<buf.size() ; i++)
107         {
108         if (outs.put(buf[i]) < 0)
109             return -1;
110         }
112     return 1;
117 static int dprintDouble(Writer &outs, double val, 
118                         int flag, int width, int precision)
121     DOMString buf;
123     //printf("int:%f  frac:%f\n", intPart, fracPart);
125     bool negative = false;
126     if (val < 0)
127         {
128         negative = true;
129         val = -val;
130         }
132     int intDigits = 0;
133     double scale = 1.0;
134     while (scale < val)
135         {
136         intDigits++;
137         scale *= 10.0;
138         }
140     double intPart;
141     double fracPart = modf(val, &intPart);
143     if (precision <= 0)
144         precision = 5;
146     //### How many pad digits?
147     int pad = width - intDigits;
148     if (precision > 0)
149         pad -= precision + 1;
150     else if (flag == '#')
151         pad--;
154     //### Signs
155     if (negative)
156         buf.push_back('-');
157     else if (flag == '+')
158         buf.push_back('+');
160     //### Prefix pad
161     if (pad > 0 && flag == '0')
162         {
163         while (pad--)
164             buf.push_back('0');
165         }
167     //### Integer digits
168     intPart = (intPart + 0.1 ) / scale;    // turn 12345.678 to .12345678
169     while (intDigits--)
170         {
171         intPart *= 10.0;
172         double dig;
173         intPart = modf(intPart, &dig);
174         char ch = '0' + (int)dig;
175         buf.push_back(ch);
176         }
177     if (buf.size() == 0)
178         buf = "0";
180     //### Decimal point
181     if (flag == '#' || precision > 0)
182         {
183         buf.push_back('.');
184         }    
186     //### Fractional digits
187     while (precision--)
188         {
189         fracPart *= 10.0;
190         double dig;
191         fracPart = modf(fracPart, &dig);
192         char ch = '0' + (int)dig;
193         buf.push_back(ch);
194         }
196     //### Left justify if requested
197     if (pad > 0 && flag == '-')
198         {
199         while (pad--)
200             buf.push_back(' ');
201         }
203     //### Output the result
204     for (unsigned int i=0 ; i<buf.size() ; i++)
205         {
206         if (outs.put(buf[i]) < 0)
207             return -1;
208         }
209     return 1;
213 /**
214  * Output a string.  We veer from the standard a tiny bit.
215  * Normally, a flag of '#' is undefined for strings.  We use
216  * it as an indicator that the user wants to XML-escape any
217  * XML entities.
218  */
219 static int dprintString(Writer &outs, const DOMString &str,
220                         int flags, int /*width*/, int /*precision*/)
222     int len = str.size();
223     if (flags == '#')
224         {
225         for (int pos = 0; pos < len; pos++)
226             {
227             XMLCh ch = (XMLCh) str[pos];
228             if (ch == '&')
229                 outs.writeString("&ampr;");
230             else if (ch == '<')
231                 outs.writeString("&lt;");
232             else if (ch == '>')
233                 outs.writeString("&gt;");
234             else if (ch == '"')
235                 outs.writeString("&quot;");
236             else if (ch == '\'')
237                 outs.writeString("&apos;");
238             else
239                 outs.put(ch);
240             }
241         }
242     else
243         {
244         outs.writeString(str);
245         }
247     return 1;
252 static int getint(const DOMString &buf, int pos, int *ret)
254     int len = buf.size();
255     if (!len)
256         {
257         *ret = 0;
258         return pos;
259         }
261     bool has_sign = false;
262     int val = 0;
263     if (buf[pos] == '-')
264         {
265         has_sign = true;
266         pos++;
267         }
268     while (pos < len)
269         {
270         XMLCh ch = buf[pos];
271         if (ch >= '0' && ch <= '9')
272             val = val * 10 + (ch - '0');
273         else
274             break;
275         pos++;
276         }
277     if (has_sign)
278         val = -val;
280     *ret = val;
282     return pos;
287 static int dprintf(Writer &outs, const DOMString &fmt, va_list ap)
290     int len = fmt.size();
292     for (int pos=0 ; pos < len ; pos++)
293         {
294         XMLCh ch = fmt[pos];
296         //## normal character
297         if (ch != '%')
298             {
299             if (outs.put(ch)<0)
300                 {
301                 return -1;
302                 }
303             continue;
304             }
306         if (++pos >= len)
307             {
308             return -1;
309             }
311         ch = fmt[pos];
313         //## is this %% ?
314         if (ch == '%') // escaped '%'
315             {
316             if (outs.put('%')<0)
317                 {
318                 return -1;
319                 }
320             continue;
321             }
323         //## flag
324         char flag = '\0';
325         if (ch == '-' || ch == '+' || ch == ' ' ||
326             ch == '#' || ch == '0')
327             {
328             flag = ch;
329             if (++pos >= len)
330                 {
331                 return -1;
332                 }
333             ch = fmt[pos];
334             }
336         //## width.precision
337         int width     = 0;
338         int precision = 0;
339         pos = getint(fmt, pos, &width);
340         if (pos >= len)
341             {
342             return -1;
343             }
344         ch = fmt[pos];
345         if (ch == '.')
346             {
347             if (++pos >= len)
348                 {
349                 return -1;
350                 }
351             pos = getint(fmt, pos, &precision);
352             if (pos >= len)
353                 {
354                 return -1;
355                 }
356             ch = fmt[pos];
357             }
359         //## length
360         char length = '\0';
361         if (ch == 'l' || ch == 'h')
362             {
363             length = ch;
364             if (++pos >= len)
365                 {
366                 return -1;
367                 }
368             ch = fmt[pos];
369             }
371         //## data type
372         switch (ch)
373             {
374             case 'f':
375             case 'g':
376                 {
377                 double val = va_arg(ap, double);
378                 dprintDouble(outs, val, flag, width, precision);
379                 break;
380                 }
381             case 'd':
382                 {
383                 long val = 0;
384                 if (length == 'l')
385                     val = va_arg(ap, long);
386                 else if (length == 'h')
387                     val = (long)va_arg(ap, int);
388                 else
389                     val = (long)va_arg(ap, int);
390                 dprintInt(outs, val, 10, flag, width, precision);
391                 break;
392                 }
393             case 'x':
394                 {
395                 long val = 0;
396                 if (length == 'l')
397                     val = va_arg(ap, long);
398                 else if (length == 'h')
399                     val = (long)va_arg(ap, int);
400                 else
401                     val = (long)va_arg(ap, int);
402                 dprintInt(outs, val, 16, flag, width, precision);
403                 break;
404                 }
405             case 's':
406                 {
407                 DOMString val = va_arg(ap, char *);
408                 dprintString(outs, val, flag, width, precision);
409                 break;
410                 }
411             default:
412                 {
413                 break;
414                 }
415             }
416         }
418     return 1;
422 //#########################################################################
423 //# B A S I C    I N P U T    S T R E A M
424 //#########################################################################
427 /**
428  *
429  */
430 BasicInputStream::BasicInputStream(const InputStream &sourceStream)
431                    : source((InputStream &)sourceStream)
433     closed = false;
436 /**
437  * Returns the number of bytes that can be read (or skipped over) from
438  * this input stream without blocking by the next caller of a method for
439  * this input stream.
440  */
441 int BasicInputStream::available()
443     if (closed)
444         return 0;
445     return source.available();
449 /**
450  *  Closes this input stream and releases any system resources
451  *  associated with the stream.
452  */
453 void BasicInputStream::close()
455     if (closed)
456         return;
457     source.close();
458     closed = true;
461 /**
462  * Reads the next byte of data from the input stream.  -1 if EOF
463  */
464 int BasicInputStream::get()
466     if (closed)
467         return -1;
468     return source.get();
473 //#########################################################################
474 //# B A S I C    O U T P U T    S T R E A M
475 //#########################################################################
477 /**
478  *
479  */
480 BasicOutputStream::BasicOutputStream(const OutputStream &destinationStream)
481                      : destination((OutputStream &)destinationStream)
483     closed = false;
486 /**
487  * Closes this output stream and releases any system resources
488  * associated with this stream.
489  */
490 void BasicOutputStream::close()
492     if (closed)
493         return;
494     destination.close();
495     closed = true;
498 /**
499  *  Flushes this output stream and forces any buffered output
500  *  bytes to be written out.
501  */
502 void BasicOutputStream::flush()
504     if (closed)
505         return;
506     destination.flush();
509 /**
510  * Writes the specified byte to this output stream.
511  */
512 int BasicOutputStream::put(XMLCh ch)
514     if (closed)
515         return -1;
516     if (destination.put(ch) < 0)
517         return -1;
518     return 1;
523 //#########################################################################
524 //# B A S I C    R E A D E R
525 //#########################################################################
528 /**
529  *
530  */
531 BasicReader::BasicReader(Reader &sourceReader)
533     source = &sourceReader;
536 /**
537  * Returns the number of bytes that can be read (or skipped over) from
538  * this reader without blocking by the next caller of a method for
539  * this reader.
540  */
541 int BasicReader::available()
543     if (source)
544         return source->available();
545     else
546         return 0;
550 /**
551  *  Closes this reader and releases any system resources
552  *  associated with the reader.
553  */
554 void BasicReader::close()
556     if (source)
557         source->close();
560 /**
561  * Reads the next byte of data from the reader.
562  */
563 int BasicReader::get()
565     if (source)
566         return source->get();
567     else
568         return -1;
576 /**
577  * Reads a line of data from the reader.
578  */
579 DOMString BasicReader::readLine()
581     DOMString str;
582     while (available() > 0)
583         {
584         XMLCh ch = get();
585         if (ch == '\n')
586             break;
587         str.push_back(ch);
588         }
589     return str;
592 /**
593  * Reads a line of data from the reader.
594  */
595 DOMString BasicReader::readWord()
597     DOMString str;
598     while (available() > 0)
599         {
600         XMLCh ch = get();
601         if (uni_is_space(ch))
602             break;
603         str.push_back(ch);
604         }
605     return str;
609 static bool getLong(DOMString &str, long *val)
611     const char *begin = str.c_str();
612     char *end;
613     long ival = strtol(begin, &end, 10);
614     if (str == end)
615         return false;
616     *val = ival;
617     return true;
620 static bool getULong(const DOMString &str, unsigned long *val)
622     DOMString tmp = str;
623     char *begin = (char *)tmp.c_str();
624     char *end;
625     unsigned long ival = strtoul(begin, &end, 10);
626     if (begin == end)
627         return false;
628     *val = ival;
629     return true;
632 static bool getDouble(const DOMString &str, double *val)
634     DOMString tmp = str;
635     const char *begin = tmp.c_str();
636     char *end;
637     double ival = strtod(begin, &end);
638     if (begin == end)
639         return false;
640     *val = ival;
641     return true;
647 /**
648  *
649  */
650 Reader &BasicReader::readBool (bool& val )
652     DOMString buf = readWord();
653     if (buf == "true")
654         val = true;
655     else
656         val = false;
657     return *this;
660 /**
661  *
662  */
663 Reader &BasicReader::readShort (short& val )
665     DOMString buf = readWord();
666     long ival;
667     if (getLong(buf, &ival))
668         val = (short) ival;
669     return *this;
672 /**
673  *
674  */
675 Reader &BasicReader::readUnsignedShort (unsigned short& val )
677     DOMString buf = readWord();
678     unsigned long ival;
679     if (getULong(buf, &ival))
680         val = (unsigned short) ival;
681     return *this;
684 /**
685  *
686  */
687 Reader &BasicReader::readInt (int& val )
689     DOMString buf = readWord();
690     long ival;
691     if (getLong(buf, &ival))
692         val = (int) ival;
693     return *this;
696 /**
697  *
698  */
699 Reader &BasicReader::readUnsignedInt (unsigned int& val )
701     DOMString buf = readWord();
702     unsigned long ival;
703     if (getULong(buf, &ival))
704         val = (unsigned int) ival;
705     return *this;
708 /**
709  *
710  */
711 Reader &BasicReader::readLong (long& val )
713     DOMString buf = readWord();
714     long ival;
715     if (getLong(buf, &ival))
716         val = ival;
717     return *this;
720 /**
721  *
722  */
723 Reader &BasicReader::readUnsignedLong (unsigned long& val )
725     DOMString buf = readWord();
726     unsigned long ival;
727     if (getULong(buf, &ival))
728         val = ival;
729     return *this;
732 /**
733  *
734  */
735 Reader &BasicReader::readFloat (float& val )
737     DOMString buf = readWord();
738     double ival;
739     if (getDouble(buf, &ival))
740         val = (float)ival;
741     return *this;
744 /**
745  *
746  */
747 Reader &BasicReader::readDouble (double& val )
749     DOMString buf = readWord();
750     double ival;
751     if (getDouble(buf, &ival))
752         val = ival;
753     return *this;
758 //#########################################################################
759 //# I N P U T    S T R E A M    R E A D E R
760 //#########################################################################
763 InputStreamReader::InputStreamReader(const InputStream &inputStreamSource)
764                      : inputStream((InputStream &)inputStreamSource)
770 /**
771  *  Close the underlying OutputStream
772  */
773 void InputStreamReader::close()
775     inputStream.close();
778 /**
779  *  Flush the underlying OutputStream
780  */
781 int InputStreamReader::available()
783     return inputStream.available();
786 /**
787  *  Overloaded to receive its bytes from an InputStream
788  *  rather than a Reader
789  */
790 int InputStreamReader::get()
792     //Do we need conversions here?
793     int ch = (XMLCh)inputStream.get();
794     return ch;
799 //#########################################################################
800 //# S T D    R E A D E R
801 //#########################################################################
804 /**
805  *
806  */
807 StdReader::StdReader()
809     inputStream = new StdInputStream();
812 /**
813  *
814  */
815 StdReader::~StdReader()
817     delete inputStream;
822 /**
823  *  Close the underlying OutputStream
824  */
825 void StdReader::close()
827     inputStream->close();
830 /**
831  *  Flush the underlying OutputStream
832  */
833 int StdReader::available()
835     return inputStream->available();
838 /**
839  *  Overloaded to receive its bytes from an InputStream
840  *  rather than a Reader
841  */
842 int StdReader::get()
844     //Do we need conversions here?
845     XMLCh ch = (XMLCh)inputStream->get();
846     return ch;
853 //#########################################################################
854 //# B A S I C    W R I T E R
855 //#########################################################################
857 /**
858  *
859  */
860 BasicWriter::BasicWriter(const Writer &destinationWriter)
862     destination = (Writer *)&destinationWriter;
865 /**
866  * Closes this writer and releases any system resources
867  * associated with this writer.
868  */
869 void BasicWriter::close()
871     if (destination)
872         destination->close();
875 /**
876  *  Flushes this output stream and forces any buffered output
877  *  bytes to be written out.
878  */
879 void BasicWriter::flush()
881     if (destination)
882         destination->flush();
885 /**
886  * Writes the specified byte to this output writer.
887  */
888 int BasicWriter::put(XMLCh ch)
890     if (destination && destination->put(ch)>=0)
891         return 1;
892     return -1;
895 /**
896  * Provide printf()-like formatting
897  */
898 /*
899 Writer &BasicWriter::printf(char const *fmt, ...)
901     va_list args;
902     va_start(args, fmt);
903     //replace this wish vsnprintf()
904     vsnprintf(formatBuf, 2047, fmt, args);
905     va_end(args);
906     writeString(formatBuf);
908     return *this;
910 */
911 Writer &BasicWriter::printf(const DOMString &fmt, ...)
913     va_list args;
914     va_start(args, fmt);
915     dprintf(*this, fmt, args);
916     return *this;
920 /**
921  * Writes the specified character to this output writer.
922  */
923 Writer &BasicWriter::writeChar(char ch)
925     XMLCh uch = ch;
926     put(uch);
927     return *this;
931 /**
932  * Writes the specified standard string to this output writer.
933  */
934 Writer &BasicWriter::writeString(const DOMString &str)
936     for (int i=0; i< (int)str.size(); i++)
937         put(str[i]);
938     return *this;
942 /**
943  *
944  */
945 Writer &BasicWriter::writeBool (bool val )
947     if (val)
948         writeString("true");
949     else
950         writeString("false");
951     return *this;
955 /**
956  *
957  */
958 Writer &BasicWriter::writeShort (short val )
960     char buf[32];
961     snprintf(buf, 31, "%d", val);
962     writeString(buf);
963     return *this;
968 /**
969  *
970  */
971 Writer &BasicWriter::writeUnsignedShort (unsigned short val )
973     char buf[32];
974     snprintf(buf, 31, "%u", val);
975     writeString(buf);
976     return *this;
979 /**
980  *
981  */
982 Writer &BasicWriter::writeInt (int val)
984     char buf[32];
985     snprintf(buf, 31, "%d", val);
986     writeString(buf);
987     return *this;
990 /**
991  *
992  */
993 Writer &BasicWriter::writeUnsignedInt (unsigned int val)
995     char buf[32];
996     snprintf(buf, 31, "%u", val);
997     writeString(buf);
998     return *this;
1001 /**
1002  *
1003  */
1004 Writer &BasicWriter::writeLong (long val)
1006     char buf[32];
1007     snprintf(buf, 31, "%ld", val);
1008     writeString(buf);
1009     return *this;
1012 /**
1013  *
1014  */
1015 Writer &BasicWriter::writeUnsignedLong(unsigned long val)
1017     char buf[32];
1018     snprintf(buf, 31, "%lu", val);
1019     writeString(buf);
1020     return *this;
1023 /**
1024  *
1025  */
1026 Writer &BasicWriter::writeFloat(float val)
1028     char buf[32];
1029     snprintf(buf, 31, "%8.3f", val);
1030     writeString(buf);
1031     return *this;
1034 /**
1035  *
1036  */
1037 Writer &BasicWriter::writeDouble(double val)
1039     char buf[32];
1040     snprintf(buf, 31, "%8.3f", val);
1041     writeString(buf);
1042     return *this;
1048 //#########################################################################
1049 //# O U T P U T    S T R E A M    W R I T E R
1050 //#########################################################################
1053 OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest)
1054                      : outputStream(outputStreamDest)
1060 /**
1061  *  Close the underlying OutputStream
1062  */
1063 void OutputStreamWriter::close()
1065     flush();
1066     outputStream.close();
1069 /**
1070  *  Flush the underlying OutputStream
1071  */
1072 void OutputStreamWriter::flush()
1074       outputStream.flush();
1077 /**
1078  *  Overloaded to redirect the output chars from the next Writer
1079  *  in the chain to an OutputStream instead.
1080  */
1081 int OutputStreamWriter::put(XMLCh ch)
1083     //Do we need conversions here?
1084     int intCh = (int) ch;
1085     if (outputStream.put(intCh) < 0)
1086         return -1;
1087     return 1;
1090 //#########################################################################
1091 //# S T D    W R I T E R
1092 //#########################################################################
1095 /**
1096  *
1097  */
1098 StdWriter::StdWriter()
1100     outputStream = new StdOutputStream();
1104 /**
1105  *
1106  */
1107 StdWriter::~StdWriter()
1109     delete outputStream;
1114 /**
1115  *  Close the underlying OutputStream
1116  */
1117 void StdWriter::close()
1119     flush();
1120     outputStream->close();
1123 /**
1124  *  Flush the underlying OutputStream
1125  */
1126 void StdWriter::flush()
1128       outputStream->flush();
1131 /**
1132  *  Overloaded to redirect the output chars from the next Writer
1133  *  in the chain to an OutputStream instead.
1134  */
1135 int StdWriter::put(XMLCh ch)
1137     //Do we need conversions here?
1138     int intCh = (int) ch;
1139     if (outputStream->put(intCh) < 0)
1140         return -1;
1141     return 1;
1155 //###############################################
1156 //# O P E R A T O R S
1157 //###############################################
1158 //# Normally these would be in the .h, but we
1159 //# just want to be absolutely certain that these
1160 //# are never multiply defined.  Easy to maintain,
1161 //# though.  Just occasionally copy/paste these
1162 //# into the .h , and replace the {} with a ;
1163 //###############################################
1168 Reader& operator>> (Reader &reader, bool& val )
1169         { return reader.readBool(val); }
1171 Reader& operator>> (Reader &reader, short &val)
1172         { return reader.readShort(val); }
1174 Reader& operator>> (Reader &reader, unsigned short &val)
1175         { return reader.readUnsignedShort(val); }
1177 Reader& operator>> (Reader &reader, int &val)
1178         { return reader.readInt(val); }
1180 Reader& operator>> (Reader &reader, unsigned int &val)
1181         { return reader.readUnsignedInt(val); }
1183 Reader& operator>> (Reader &reader, long &val)
1184         { return reader.readLong(val); }
1186 Reader& operator>> (Reader &reader, unsigned long &val)
1187         { return reader.readUnsignedLong(val); }
1189 Reader& operator>> (Reader &reader, float &val)
1190         { return reader.readFloat(val); }
1192 Reader& operator>> (Reader &reader, double &val)
1193         { return reader.readDouble(val); }
1198 Writer& operator<< (Writer &writer, char val)
1199     { return writer.writeChar(val); }
1201 Writer& operator<< (Writer &writer, const DOMString &val)
1202     { return writer.writeString(val); }
1204 Writer& operator<< (Writer &writer, bool val)
1205     { return writer.writeBool(val); }
1207 Writer& operator<< (Writer &writer, short val)
1208     { return writer.writeShort(val); }
1210 Writer& operator<< (Writer &writer, unsigned short val)
1211     { return writer.writeUnsignedShort(val); }
1213 Writer& operator<< (Writer &writer, int val)
1214     { return writer.writeInt(val); }
1216 Writer& operator<< (Writer &writer, unsigned int val)
1217     { return writer.writeUnsignedInt(val); }
1219 Writer& operator<< (Writer &writer, long val)
1220     { return writer.writeLong(val); }
1222 Writer& operator<< (Writer &writer, unsigned long val)
1223     { return writer.writeUnsignedLong(val); }
1225 Writer& operator<< (Writer &writer, float val)
1226     { return writer.writeFloat(val); }
1228 Writer& operator<< (Writer &writer, double val)
1229     { return writer.writeDouble(val); }
1233 }  //namespace io
1234 }  //namespace dom
1235 }  //namespace w3c
1236 }  //namespace org
1239 //#########################################################################
1240 //# E N D    O F    F I L E
1241 //#########################################################################