1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #ifndef SEEN_INKSCAPE_IO_INKSCAPESTREAM_H
3 #define SEEN_INKSCAPE_IO_INKSCAPESTREAM_H
4 /*
5  * Authors:
6  *   Bob Jamison <rjamison@titan.com>
7  *
8  * Copyright (C) 2004 Inkscape.org
9  *
10  * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11  */
12 
13 #include <cstdio>
14 #include <glibmm/ustring.h>
15 
16 namespace Inkscape
17 {
18 namespace IO
19 {
20 
21 class StreamException : public std::exception
22 {
23 public:
StreamException(Glib::ustring theReason)24     StreamException(Glib::ustring theReason) noexcept
25         : reason(std::move(theReason))
26     {}
27     ~StreamException() noexcept override
28         = default;
what()29     char const *what() const noexcept override
30         { return reason.c_str(); }
31 
32 private:
33     Glib::ustring reason;
34 
35 };
36 
37 //#########################################################################
38 //# I N P U T    S T R E A M
39 //#########################################################################
40 
41 /**
42  * This interface is the base of all input stream classes.  Users who wish
43  * to make an InputStream that is part of a chain should inherit from
44  * BasicInputStream.  Inherit from this class to make a source endpoint,
45  * such as a URI or buffer.
46  *
47  */
48 class InputStream
49 {
50 
51 public:
52 
53     /**
54      * Constructor.
55      */
56     InputStream() = default;
57 
58     /**
59      * Destructor
60      */
61     virtual ~InputStream() = default;
62 
63     /**
64      * Return the number of bytes that are currently available
65      * to be read
66      */
67     virtual int available() = 0;
68 
69     /**
70      * Do whatever it takes to 'close' this input stream
71      * The most likely implementation of this method will be
72      * for endpoints that use a resource for their data.
73      */
74     virtual void close() = 0;
75 
76     /**
77      * Read one byte from this input stream.  This is a blocking
78      * call.  If no data is currently available, this call will
79      * not return until it exists.  If the user does not want
80      * their code to block,  then the usual solution is:
81      *     if (available() > 0)
82      *         myChar = get();
83      * This call returns -1 on end-of-file.
84      */
85     virtual int get() = 0;
86 
87 }; // class InputStream
88 
89 
90 
91 
92 /**
93  * This is the class that most users should inherit, to provide
94  * their own streams.
95  *
96  */
97 class BasicInputStream : public InputStream
98 {
99 
100 public:
101 
102     BasicInputStream(InputStream &sourceStream);
103 
104     ~BasicInputStream() override = default;
105 
106     int available() override;
107 
108     void close() override;
109 
110     int get() override;
111 
112 protected:
113 
114     bool closed;
115 
116     InputStream &source;
117 
118 private:
119 
120 
121 }; // class BasicInputStream
122 
123 
124 
125 /**
126  * Convenience class for reading from standard input
127  */
128 class StdInputStream : public InputStream
129 {
130 public:
131 
available()132     int available() override
133         { return 0; }
134 
close()135     void close() override
136         { /* do nothing */ }
137 
get()138     int get() override
139         {  return getchar(); }
140 
141 };
142 
143 
144 
145 
146 
147 
148 //#########################################################################
149 //# O U T P U T    S T R E A M
150 //#########################################################################
151 
152 /**
153  * This interface is the base of all input stream classes.  Users who wish
154  * to make an OutputStream that is part of a chain should inherit from
155  * BasicOutputStream.  Inherit from this class to make a destination endpoint,
156  * such as a URI or buffer.
157  */
158 class OutputStream
159 {
160 
161 public:
162 
163     /**
164      * Constructor.
165      */
166     OutputStream() = default;
167 
168     /**
169      * Destructor
170      */
171     virtual ~OutputStream() = default;
172 
173     /**
174      * This call should
175      *  1.  flush itself
176      *  2.  close itself
177      *  3.  close the destination stream
178      */
179     virtual void close() = 0;
180 
181     /**
182      * This call should push any pending data it might have to
183      * the destination stream.  It should NOT call flush() on
184      * the destination stream.
185      */
186     virtual void flush() = 0;
187 
188     /**
189      * Send one byte to the destination stream.
190      */
191     virtual int put(char ch) = 0;
192 
193 
194 }; // class OutputStream
195 
196 
197 /**
198  * This is the class that most users should inherit, to provide
199  * their own output streams.
200  */
201 class BasicOutputStream : public OutputStream
202 {
203 
204 public:
205 
206     BasicOutputStream(OutputStream &destinationStream);
207 
208     ~BasicOutputStream() override = default;
209 
210     void close() override;
211 
212     void flush() override;
213 
214     int put(char ch) override;
215 
216 protected:
217 
218     bool closed;
219 
220     OutputStream &destination;
221 
222 
223 }; // class BasicOutputStream
224 
225 
226 
227 /**
228  * Convenience class for writing to standard output
229  */
230 class StdOutputStream : public OutputStream
231 {
232 public:
233 
close()234     void close() override
235         { }
236 
flush()237     void flush() override
238         { }
239 
put(char ch)240     int put(char ch) override
241         {return  putchar(ch); }
242 
243 };
244 
245 
246 
247 
248 //#########################################################################
249 //# R E A D E R
250 //#########################################################################
251 
252 
253 /**
254  * This interface and its descendants are for unicode character-oriented input
255  *
256  */
257 class Reader
258 {
259 
260 public:
261 
262     /**
263      * Constructor.
264      */
265     Reader() = default;
266 
267     /**
268      * Destructor
269      */
270     virtual ~Reader() = default;
271 
272 
273     virtual int available() = 0;
274 
275     virtual void close() = 0;
276 
277     virtual char get() = 0;
278 
279     virtual Glib::ustring readLine() = 0;
280 
281     virtual Glib::ustring readWord() = 0;
282 
283     /* Input formatting */
284     virtual const Reader& readBool (bool& val ) = 0;
285     virtual const Reader& operator>> (bool& val ) = 0;
286 
287     virtual const Reader& readShort (short &val) = 0;
288     virtual const Reader& operator>> (short &val) = 0;
289 
290     virtual const Reader& readUnsignedShort (unsigned short &val) = 0;
291     virtual const Reader& operator>> (unsigned short &val) = 0;
292 
293     virtual const Reader& readInt (int &val) = 0;
294     virtual const Reader& operator>> (int &val) = 0;
295 
296     virtual const Reader& readUnsignedInt (unsigned int &val) = 0;
297     virtual const Reader& operator>> (unsigned int &val) = 0;
298 
299     virtual const Reader& readLong (long &val) = 0;
300     virtual const Reader& operator>> (long &val) = 0;
301 
302     virtual const Reader& readUnsignedLong (unsigned long &val) = 0;
303     virtual const Reader& operator>> (unsigned long &val) = 0;
304 
305     virtual const Reader& readFloat (float &val) = 0;
306     virtual const Reader& operator>> (float &val) = 0;
307 
308     virtual const Reader& readDouble (double &val) = 0;
309     virtual const Reader& operator>> (double &val) = 0;
310 
311 }; // interface Reader
312 
313 
314 
315 /**
316  * This class and its descendants are for unicode character-oriented input
317  *
318  */
319 class BasicReader : public Reader
320 {
321 
322 public:
323 
324     BasicReader(Reader &sourceStream);
325 
326     ~BasicReader() override = default;
327 
328     int available() override;
329 
330     void close() override;
331 
332     char get() override;
333 
334     Glib::ustring readLine() override;
335 
336     Glib::ustring readWord() override;
337 
338     /* Input formatting */
339     const Reader& readBool (bool& val ) override;
340     const Reader& operator>> (bool& val ) override
341         { return readBool(val); }
342 
343     const Reader& readShort (short &val) override;
344     const Reader& operator>> (short &val) override
345         { return readShort(val); }
346 
347     const Reader& readUnsignedShort (unsigned short &val) override;
348     const Reader& operator>> (unsigned short &val) override
349         { return readUnsignedShort(val); }
350 
351     const Reader& readInt (int &val) override;
352     const Reader& operator>> (int &val) override
353         { return readInt(val); }
354 
355     const Reader& readUnsignedInt (unsigned int &val) override;
356     const Reader& operator>> (unsigned int &val) override
357         { return readUnsignedInt(val); }
358 
359     const Reader& readLong (long &val) override;
360     const Reader& operator>> (long &val) override
361         { return readLong(val); }
362 
363     const Reader& readUnsignedLong (unsigned long &val) override;
364     const Reader& operator>> (unsigned long &val) override
365         { return readUnsignedLong(val); }
366 
367     const Reader& readFloat (float &val) override;
368     const Reader& operator>> (float &val) override
369         { return readFloat(val); }
370 
371     const Reader& readDouble (double &val) override;
372     const Reader& operator>> (double &val) override
373         { return readDouble(val); }
374 
375 
376 protected:
377 
378     Reader *source;
379 
BasicReader()380     BasicReader()
381         { source = nullptr; }
382 
383 private:
384 
385 }; // class BasicReader
386 
387 
388 
389 /**
390  * Class for placing a Reader on an open InputStream
391  *
392  */
393 class InputStreamReader : public BasicReader
394 {
395 public:
396 
397     InputStreamReader(InputStream &inputStreamSource);
398 
399     /*Overload these 3 for your implementation*/
400     int available() override;
401 
402     void close() override;
403 
404     char get() override;
405 
406 
407 private:
408 
409     InputStream &inputStream;
410 
411 
412 };
413 
414 /**
415  * Convenience class for reading formatted from standard input
416  *
417  */
418 class StdReader : public BasicReader
419 {
420 public:
421 
422     StdReader();
423 
424     ~StdReader() override;
425 
426     /*Overload these 3 for your implementation*/
427     int available() override;
428 
429     void close() override;
430 
431     char get() override;
432 
433 
434 private:
435 
436     InputStream *inputStream;
437 
438 
439 };
440 
441 
442 
443 
444 
445 //#########################################################################
446 //# W R I T E R
447 //#########################################################################
448 
449 /**
450  * This interface and its descendants are for unicode character-oriented output
451  *
452  */
453 class Writer
454 {
455 
456 public:
457 
458     /**
459      * Constructor.
460      */
461     Writer() = default;
462 
463     /**
464      * Destructor
465      */
466     virtual ~Writer() = default;
467 
468     virtual void close() = 0;
469 
470     virtual void flush() = 0;
471 
472     virtual void put(char ch) = 0;
473 
474     /* Formatted output */
475     virtual Writer& printf(char const *fmt, ...) G_GNUC_PRINTF(2,3) = 0;
476 
477     virtual Writer& writeChar(char val) = 0;
478 
479     virtual Writer& writeUString(const Glib::ustring &val) = 0;
480 
481     virtual Writer& writeStdString(const std::string &val) = 0;
482 
483     virtual Writer& writeString(const char *str) = 0;
484 
485     virtual Writer& writeBool (bool val ) = 0;
486 
487     virtual Writer& writeShort (short val ) = 0;
488 
489     virtual Writer& writeUnsignedShort (unsigned short val ) = 0;
490 
491     virtual Writer& writeInt (int val ) = 0;
492 
493     virtual Writer& writeUnsignedInt (unsigned int val ) = 0;
494 
495     virtual Writer& writeLong (long val ) = 0;
496 
497     virtual Writer& writeUnsignedLong (unsigned long val ) = 0;
498 
499     virtual Writer& writeFloat (float val ) = 0;
500 
501     virtual Writer& writeDouble (double val ) = 0;
502 
503 
504 
505 }; // interface Writer
506 
507 
508 /**
509  * This class and its descendants are for unicode character-oriented output
510  *
511  */
512 class BasicWriter : public Writer
513 {
514 
515 public:
516 
517     BasicWriter(Writer &destinationWriter);
518 
519     ~BasicWriter() override = default;
520 
521     /*Overload these 3 for your implementation*/
522     void close() override;
523 
524     void flush() override;
525 
526     void put(char ch) override;
527 
528 
529 
530     /* Formatted output */
531     Writer &printf(char const *fmt, ...) override G_GNUC_PRINTF(2,3);
532 
533     Writer& writeChar(char val) override;
534 
535     Writer& writeUString(const Glib::ustring &val) override;
536 
537     Writer& writeStdString(const std::string &val) override;
538 
539     Writer& writeString(const char *str) override;
540 
541     Writer& writeBool (bool val ) override;
542 
543     Writer& writeShort (short val ) override;
544 
545     Writer& writeUnsignedShort (unsigned short val ) override;
546 
547     Writer& writeInt (int val ) override;
548 
549     Writer& writeUnsignedInt (unsigned int val ) override;
550 
551     Writer& writeLong (long val ) override;
552 
553     Writer& writeUnsignedLong (unsigned long val ) override;
554 
555     Writer& writeFloat (float val ) override;
556 
557     Writer& writeDouble (double val ) override;
558 
559 
560 protected:
561 
562     Writer *destination;
563 
BasicWriter()564     BasicWriter()
565         { destination = nullptr; }
566 
567 private:
568 
569 }; // class BasicWriter
570 
571 
572 
573 Writer& operator<< (Writer &writer, char val);
574 
575 Writer& operator<< (Writer &writer, Glib::ustring &val);
576 
577 Writer& operator<< (Writer &writer, std::string &val);
578 
579 Writer& operator<< (Writer &writer, char const *val);
580 
581 Writer& operator<< (Writer &writer, bool val);
582 
583 Writer& operator<< (Writer &writer, short val);
584 
585 Writer& operator<< (Writer &writer, unsigned short val);
586 
587 Writer& operator<< (Writer &writer, int val);
588 
589 Writer& operator<< (Writer &writer, unsigned int val);
590 
591 Writer& operator<< (Writer &writer, long val);
592 
593 Writer& operator<< (Writer &writer, unsigned long val);
594 
595 Writer& operator<< (Writer &writer, float val);
596 
597 Writer& operator<< (Writer &writer, double val);
598 
599 
600 
601 
602 /**
603  * Class for placing a Writer on an open OutputStream
604  *
605  */
606 class OutputStreamWriter : public BasicWriter
607 {
608 public:
609 
610     OutputStreamWriter(OutputStream &outputStreamDest);
611 
612     /*Overload these 3 for your implementation*/
613     void close() override;
614 
615     void flush() override;
616 
617     void put(char ch) override;
618 
619 
620 private:
621 
622     OutputStream &outputStream;
623 
624 
625 };
626 
627 
628 /**
629  * Convenience class for writing to standard output
630  */
631 class StdWriter : public BasicWriter
632 {
633 public:
634     StdWriter();
635 
636     ~StdWriter() override;
637 
638 
639     void close() override;
640 
641 
642     void flush() override;
643 
644 
645     void put(char ch) override;
646 
647 
648 private:
649 
650     OutputStream *outputStream;
651 
652 };
653 
654 //#########################################################################
655 //# U T I L I T Y
656 //#########################################################################
657 
658 void pipeStream(InputStream &source, OutputStream &dest);
659 
660 
661 
662 } // namespace IO
663 } // namespace Inkscape
664 
665 
666 #endif // SEEN_INKSCAPE_IO_INKSCAPESTREAM_H
667