1 /**
2 * Our base input/output stream classes. These are is directly
3 * inherited from iostreams, and includes any extra
4 * functionality that we might need.
5 *
6 * Authors:
7 * Bob Jamison <rjamison@titan.com>
8 *
9 * Copyright (C) 2004 Inkscape.org
10 *
11 * Released under GNU GPL, read the file 'COPYING' for more information
12 */
15 #include "inkscapestream.h"
17 namespace Inkscape
18 {
19 namespace IO
20 {
22 //#########################################################################
23 //# U T I L I T Y
24 //#########################################################################
26 void pipeStream(InputStream &source, OutputStream &dest)
27 {
28 for (;;)
29 {
30 int ch = source.get();
31 if (ch<0)
32 break;
33 dest.put(ch);
34 }
35 dest.flush();
36 }
38 //#########################################################################
39 //# B A S I C I N P U T S T R E A M
40 //#########################################################################
43 /**
44 *
45 */
46 BasicInputStream::BasicInputStream(InputStream &sourceStream)
47 : source(sourceStream)
48 {
49 closed = false;
50 }
52 /**
53 * Returns the number of bytes that can be read (or skipped over) from
54 * this input stream without blocking by the next caller of a method for
55 * this input stream.
56 */
57 int BasicInputStream::available()
58 {
59 if (closed)
60 return 0;
61 return source.available();
62 }
65 /**
66 * Closes this input stream and releases any system resources
67 * associated with the stream.
68 */
69 void BasicInputStream::close()
70 {
71 if (closed)
72 return;
73 source.close();
74 closed = true;
75 }
77 /**
78 * Reads the next byte of data from the input stream. -1 if EOF
79 */
80 int BasicInputStream::get()
81 {
82 if (closed)
83 return -1;
84 return source.get();
85 }
89 //#########################################################################
90 //# B A S I C O U T P U T S T R E A M
91 //#########################################################################
93 /**
94 *
95 */
96 BasicOutputStream::BasicOutputStream(OutputStream &destinationStream)
97 : destination(destinationStream)
98 {
99 closed = false;
100 }
102 /**
103 * Closes this output stream and releases any system resources
104 * associated with this stream.
105 */
106 void BasicOutputStream::close()
107 {
108 if (closed)
109 return;
110 destination.close();
111 closed = true;
112 }
114 /**
115 * Flushes this output stream and forces any buffered output
116 * bytes to be written out.
117 */
118 void BasicOutputStream::flush()
119 {
120 if (closed)
121 return;
122 destination.flush();
123 }
125 /**
126 * Writes the specified byte to this output stream.
127 */
128 void BasicOutputStream::put(int ch)
129 {
130 if (closed)
131 return;
132 destination.put(ch);
133 }
137 //#########################################################################
138 //# B A S I C R E A D E R
139 //#########################################################################
142 /**
143 *
144 */
145 BasicReader::BasicReader(Reader &sourceReader)
146 {
147 source = &sourceReader;
148 }
150 /**
151 * Returns the number of bytes that can be read (or skipped over) from
152 * this reader without blocking by the next caller of a method for
153 * this reader.
154 */
155 int BasicReader::available()
156 {
157 if (source)
158 return source->available();
159 else
160 return 0;
161 }
164 /**
165 * Closes this reader and releases any system resources
166 * associated with the reader.
167 */
168 void BasicReader::close()
169 {
170 if (source)
171 source->close();
172 }
174 /**
175 * Reads the next byte of data from the reader.
176 */
177 gunichar BasicReader::get()
178 {
179 if (source)
180 return source->get();
181 else
182 return (gunichar)-1;
183 }
190 /**
191 * Reads a line of data from the reader.
192 */
193 Glib::ustring BasicReader::readLine()
194 {
195 Glib::ustring str;
196 while (available() > 0)
197 {
198 gunichar ch = get();
199 if (ch == '\n')
200 break;
201 str.push_back(ch);
202 }
203 return str;
204 }
206 /**
207 * Reads a line of data from the reader.
208 */
209 Glib::ustring BasicReader::readWord()
210 {
211 Glib::ustring str;
212 while (available() > 0)
213 {
214 gunichar ch = get();
215 if (!g_unichar_isprint(ch))
216 break;
217 str.push_back(ch);
218 }
219 return str;
220 }
223 static bool getLong(Glib::ustring &str, long *val)
224 {
225 const char *begin = str.raw().c_str();
226 char *end;
227 long ival = strtol(begin, &end, 10);
228 if (str == end)
229 return false;
230 *val = ival;
231 return true;
232 }
234 static bool getULong(Glib::ustring &str, unsigned long *val)
235 {
236 const char *begin = str.raw().c_str();
237 char *end;
238 unsigned long ival = strtoul(begin, &end, 10);
239 if (str == end)
240 return false;
241 *val = ival;
242 return true;
243 }
245 static bool getDouble(Glib::ustring &str, double *val)
246 {
247 const char *begin = str.raw().c_str();
248 char *end;
249 double ival = strtod(begin, &end);
250 if (str == end)
251 return false;
252 *val = ival;
253 return true;
254 }
262 /**
263 *
264 */
265 const Reader &BasicReader::readBool (bool& val )
266 {
267 Glib::ustring buf = readWord();
268 if (buf == "true")
269 val = true;
270 else
271 val = false;
272 return *this;
273 }
275 /**
276 *
277 */
278 const Reader &BasicReader::readShort (short& val )
279 {
280 Glib::ustring buf = readWord();
281 long ival;
282 if (getLong(buf, &ival))
283 val = (short) ival;
284 return *this;
285 }
287 /**
288 *
289 */
290 const Reader &BasicReader::readUnsignedShort (unsigned short& val )
291 {
292 Glib::ustring buf = readWord();
293 unsigned long ival;
294 if (getULong(buf, &ival))
295 val = (unsigned short) ival;
296 return *this;
297 }
299 /**
300 *
301 */
302 const Reader &BasicReader::readInt (int& val )
303 {
304 Glib::ustring buf = readWord();
305 long ival;
306 if (getLong(buf, &ival))
307 val = (int) ival;
308 return *this;
309 }
311 /**
312 *
313 */
314 const Reader &BasicReader::readUnsignedInt (unsigned int& val )
315 {
316 Glib::ustring buf = readWord();
317 unsigned long ival;
318 if (getULong(buf, &ival))
319 val = (unsigned int) ival;
320 return *this;
321 }
323 /**
324 *
325 */
326 const Reader &BasicReader::readLong (long& val )
327 {
328 Glib::ustring buf = readWord();
329 long ival;
330 if (getLong(buf, &ival))
331 val = ival;
332 return *this;
333 }
335 /**
336 *
337 */
338 const Reader &BasicReader::readUnsignedLong (unsigned long& val )
339 {
340 Glib::ustring buf = readWord();
341 unsigned long ival;
342 if (getULong(buf, &ival))
343 val = ival;
344 return *this;
345 }
347 /**
348 *
349 */
350 const Reader &BasicReader::readFloat (float& val )
351 {
352 Glib::ustring buf = readWord();
353 double ival;
354 if (getDouble(buf, &ival))
355 val = (float)ival;
356 return *this;
357 }
359 /**
360 *
361 */
362 const Reader &BasicReader::readDouble (double& val )
363 {
364 Glib::ustring buf = readWord();
365 double ival;
366 if (getDouble(buf, &ival))
367 val = ival;
368 return *this;
369 }
373 //#########################################################################
374 //# I N P U T S T R E A M R E A D E R
375 //#########################################################################
378 InputStreamReader::InputStreamReader(InputStream &inputStreamSource)
379 : inputStream(inputStreamSource)
380 {
381 }
385 /**
386 * Close the underlying OutputStream
387 */
388 void InputStreamReader::close()
389 {
390 inputStream.close();
391 }
393 /**
394 * Flush the underlying OutputStream
395 */
396 int InputStreamReader::available()
397 {
398 return inputStream.available();
399 }
401 /**
402 * Overloaded to receive its bytes from an InputStream
403 * rather than a Reader
404 */
405 gunichar InputStreamReader::get()
406 {
407 //Do we need conversions here?
408 gunichar ch = (gunichar)inputStream.get();
409 return ch;
410 }
414 //#########################################################################
415 //# S T D R E A D E R
416 //#########################################################################
419 /**
420 *
421 */
422 StdReader::StdReader()
423 {
424 inputStream = new StdInputStream();
425 }
427 /**
428 *
429 */
430 StdReader::~StdReader()
431 {
432 delete inputStream;
433 }
437 /**
438 * Close the underlying OutputStream
439 */
440 void StdReader::close()
441 {
442 inputStream->close();
443 }
445 /**
446 * Flush the underlying OutputStream
447 */
448 int StdReader::available()
449 {
450 return inputStream->available();
451 }
453 /**
454 * Overloaded to receive its bytes from an InputStream
455 * rather than a Reader
456 */
457 gunichar StdReader::get()
458 {
459 //Do we need conversions here?
460 gunichar ch = (gunichar)inputStream->get();
461 return ch;
462 }
468 //#########################################################################
469 //# B A S I C W R I T E R
470 //#########################################################################
472 /**
473 *
474 */
475 BasicWriter::BasicWriter(Writer &destinationWriter)
476 {
477 destination = &destinationWriter;
478 }
480 /**
481 * Closes this writer and releases any system resources
482 * associated with this writer.
483 */
484 void BasicWriter::close()
485 {
486 if (destination)
487 destination->close();
488 }
490 /**
491 * Flushes this output stream and forces any buffered output
492 * bytes to be written out.
493 */
494 void BasicWriter::flush()
495 {
496 if (destination)
497 destination->flush();
498 }
500 /**
501 * Writes the specified byte to this output writer.
502 */
503 void BasicWriter::put(gunichar ch)
504 {
505 if (destination)
506 destination->put(ch);
507 }
509 /**
510 * Provide printf()-like formatting
511 */
512 Writer &BasicWriter::printf(char *fmt, ...)
513 {
514 va_list args;
515 va_start(args, fmt);
516 gchar *buf = g_strdup_vprintf(fmt, args);
517 va_end(args);
518 if (buf) {
519 writeString(buf);
520 g_free(buf);
521 }
522 return *this;
523 }
524 /**
525 * Writes the specified character to this output writer.
526 */
527 Writer &BasicWriter::writeChar(char ch)
528 {
529 gunichar uch = ch;
530 put(uch);
531 return *this;
532 }
535 /**
536 * Writes the specified unicode string to this output writer.
537 */
538 Writer &BasicWriter::writeUString(Glib::ustring &str)
539 {
540 for (int i=0; i< (int)str.size(); i++)
541 put(str[i]);
542 return *this;
543 }
545 /**
546 * Writes the specified standard string to this output writer.
547 */
548 Writer &BasicWriter::writeStdString(std::string &str)
549 {
550 Glib::ustring tmp(str);
551 writeUString(tmp);
552 return *this;
553 }
555 /**
556 * Writes the specified character string to this output writer.
557 */
558 Writer &BasicWriter::writeString(const char *str)
559 {
560 Glib::ustring tmp;
561 if (str)
562 tmp = str;
563 else
564 tmp = "null";
565 writeUString(tmp);
566 return *this;
567 }
572 /**
573 *
574 */
575 Writer &BasicWriter::writeBool (bool val )
576 {
577 if (val)
578 writeString("true");
579 else
580 writeString("false");
581 return *this;
582 }
585 /**
586 *
587 */
588 Writer &BasicWriter::writeShort (short val )
589 {
590 gchar *buf = g_strdup_printf("%d", val);
591 if (buf) {
592 writeString(buf);
593 g_free(buf);
594 }
595 return *this;
596 }
600 /**
601 *
602 */
603 Writer &BasicWriter::writeUnsignedShort (unsigned short val )
604 {
605 gchar *buf = g_strdup_printf("%u", val);
606 if (buf) {
607 writeString(buf);
608 g_free(buf);
609 }
610 return *this;
611 }
613 /**
614 *
615 */
616 Writer &BasicWriter::writeInt (int val)
617 {
618 gchar *buf = g_strdup_printf("%d", val);
619 if (buf) {
620 writeString(buf);
621 g_free(buf);
622 }
623 return *this;
624 }
626 /**
627 *
628 */
629 Writer &BasicWriter::writeUnsignedInt (unsigned int val)
630 {
631 gchar *buf = g_strdup_printf("%u", val);
632 if (buf) {
633 writeString(buf);
634 g_free(buf);
635 }
636 return *this;
637 }
639 /**
640 *
641 */
642 Writer &BasicWriter::writeLong (long val)
643 {
644 gchar *buf = g_strdup_printf("%ld", val);
645 if (buf) {
646 writeString(buf);
647 g_free(buf);
648 }
649 return *this;
650 }
652 /**
653 *
654 */
655 Writer &BasicWriter::writeUnsignedLong(unsigned long val)
656 {
657 gchar *buf = g_strdup_printf("%lu", val);
658 if (buf) {
659 writeString(buf);
660 g_free(buf);
661 }
662 return *this;
663 }
665 /**
666 *
667 */
668 Writer &BasicWriter::writeFloat(float val)
669 {
670 #if 1
671 gchar *buf = g_strdup_printf("%8.3f", val);
672 if (buf) {
673 writeString(buf);
674 g_free(buf);
675 }
676 #else
677 std::string tmp = ftos(val, 'g', 8, 3, 0);
678 writeStdString(tmp);
679 #endif
680 return *this;
681 }
683 /**
684 *
685 */
686 Writer &BasicWriter::writeDouble(double val)
687 {
688 #if 1
689 gchar *buf = g_strdup_printf("%8.3f", val);
690 if (buf) {
691 writeString(buf);
692 g_free(buf);
693 }
694 #else
695 std::string tmp = ftos(val, 'g', 8, 3, 0);
696 writeStdString(tmp);
697 #endif
698 return *this;
699 }
702 Writer& operator<< (Writer &writer, char val)
703 { return writer.writeChar(val); }
705 Writer& operator<< (Writer &writer, Glib::ustring &val)
706 { return writer.writeUString(val); }
708 Writer& operator<< (Writer &writer, std::string &val)
709 { return writer.writeStdString(val); }
711 Writer& operator<< (Writer &writer, char *val)
712 { return writer.writeString(val); }
714 Writer& operator<< (Writer &writer, bool val)
715 { return writer.writeBool(val); }
717 Writer& operator<< (Writer &writer, short val)
718 { return writer.writeShort(val); }
720 Writer& operator<< (Writer &writer, unsigned short val)
721 { return writer.writeUnsignedShort(val); }
723 Writer& operator<< (Writer &writer, int val)
724 { return writer.writeInt(val); }
726 Writer& operator<< (Writer &writer, unsigned int val)
727 { return writer.writeUnsignedInt(val); }
729 Writer& operator<< (Writer &writer, long val)
730 { return writer.writeLong(val); }
732 Writer& operator<< (Writer &writer, unsigned long val)
733 { return writer.writeUnsignedLong(val); }
735 Writer& operator<< (Writer &writer, float val)
736 { return writer.writeFloat(val); }
738 Writer& operator<< (Writer &writer, double val)
739 { return writer.writeDouble(val); }
743 //#########################################################################
744 //# O U T P U T S T R E A M W R I T E R
745 //#########################################################################
748 OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest)
749 : outputStream(outputStreamDest)
750 {
751 }
755 /**
756 * Close the underlying OutputStream
757 */
758 void OutputStreamWriter::close()
759 {
760 flush();
761 outputStream.close();
762 }
764 /**
765 * Flush the underlying OutputStream
766 */
767 void OutputStreamWriter::flush()
768 {
769 outputStream.flush();
770 }
772 /**
773 * Overloaded to redirect the output chars from the next Writer
774 * in the chain to an OutputStream instead.
775 */
776 void OutputStreamWriter::put(gunichar ch)
777 {
778 //Do we need conversions here?
779 int intCh = (int) ch;
780 outputStream.put(intCh);
781 }
783 //#########################################################################
784 //# S T D W R I T E R
785 //#########################################################################
788 /**
789 *
790 */
791 StdWriter::StdWriter()
792 {
793 outputStream = new StdOutputStream();
794 }
797 /**
798 *
799 */
800 StdWriter::~StdWriter()
801 {
802 delete outputStream;
803 }
807 /**
808 * Close the underlying OutputStream
809 */
810 void StdWriter::close()
811 {
812 flush();
813 outputStream->close();
814 }
816 /**
817 * Flush the underlying OutputStream
818 */
819 void StdWriter::flush()
820 {
821 outputStream->flush();
822 }
824 /**
825 * Overloaded to redirect the output chars from the next Writer
826 * in the chain to an OutputStream instead.
827 */
828 void StdWriter::put(gunichar ch)
829 {
830 //Do we need conversions here?
831 int intCh = (int) ch;
832 outputStream->put(intCh);
833 }
836 } // namespace IO
837 } // namespace Inkscape
840 //#########################################################################
841 //# E N D O F F I L E
842 //#########################################################################