1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 
4 #ifndef OutputCharStream_INCLUDED
5 #define OutputCharStream_INCLUDED 1
6 
7 #include "types.h"
8 #include <stddef.h>
9 #include "StringC.h"
10 #include "Owner.h"
11 #include "CodingSystem.h"
12 #include "OutputByteStream.h"
13 
14 #ifdef SP_NAMESPACE
15 namespace SP_NAMESPACE {
16 #endif
17 
18 class SP_API OutputCharStream {
19 public:
20   enum Newline { newline };
21   typedef void (*Escaper)(OutputCharStream &, Char);
22   OutputCharStream();
23   virtual ~OutputCharStream();
24   OutputCharStream &put(Char);
25   OutputCharStream &write(const Char *, size_t);
26   virtual void flush() = 0;
27   virtual void setEscaper(Escaper);
28 
29   OutputCharStream &operator<<(char);
30   OutputCharStream &operator<<(const char *);
31   OutputCharStream &operator<<(const StringC &);
32   OutputCharStream &operator<<(unsigned long);
33   OutputCharStream &operator<<(int);
34   OutputCharStream &operator<<(Newline);
35 private:
36   OutputCharStream(const OutputCharStream &);	// undefined
37   void operator=(const OutputCharStream &);	// undefined
38 
39   virtual void flushBuf(Char) = 0;
40 protected:
41   Char *ptr_;
42   Char *end_;
43 };
44 
45 class SP_API EncodeOutputCharStream : public OutputCharStream,
46                             private Encoder::Handler {
47 public:
48   EncodeOutputCharStream();
49   // the OutputByteStream will not be deleted
50   EncodeOutputCharStream(OutputByteStream *, const OutputCodingSystem *);
51   ~EncodeOutputCharStream();
52   void open(OutputByteStream *, const OutputCodingSystem *);
53   void flush();
54   void setEscaper(Escaper);
55 private:
56   EncodeOutputCharStream(const EncodeOutputCharStream &); // undefined
57   void operator=(const EncodeOutputCharStream &);	    // undefined
58   EncodeOutputCharStream(OutputByteStream *, Encoder *);
59   void allocBuf(int bytesPerChar);
60   void flushBuf(Char);
61   void handleUnencodable(Char c, OutputByteStream *);
62   Char *buf_;
63   OutputByteStream *byteStream_;
64   Encoder *encoder_;
65   Owner<Encoder> ownedEncoder_;
66   Escaper escaper_;
67 };
68 
69 class SP_API StrOutputCharStream : public OutputCharStream {
70 public:
71   StrOutputCharStream();
72   ~StrOutputCharStream();
73   void extractString(StringC &);
74   void flush();
75 private:
76   void flushBuf(Char);
77   void sync(size_t);
78   StrOutputCharStream(const StrOutputCharStream &); // undefined
79   void operator=(const StrOutputCharStream &);	    // undefined
80   Char *buf_;
81   size_t bufSize_;
82 };
83 
84 class SP_API RecordOutputCharStream : public OutputCharStream {
85 public:
86   RecordOutputCharStream(OutputCharStream *);
87   ~RecordOutputCharStream();
88   void flush();
89   void setEscaper(Escaper);
90 private:
91   RecordOutputCharStream(const RecordOutputCharStream &); // undefined
92   void operator=(const RecordOutputCharStream &);	  // undefined
93   void flushBuf(Char);
94   void outputBuf();
95 
96   OutputCharStream *os_;
97   enum { bufSize_ = 1024 };
98   Char buf_[bufSize_];
99 };
100 
101 inline
put(Char c)102 OutputCharStream &OutputCharStream::put(Char c)
103 {
104   if (ptr_ < end_)
105     *ptr_++ = c;
106   else
107     flushBuf(c);
108   return *this;
109 }
110 
111 inline
112 OutputCharStream &OutputCharStream::operator<<(char c)
113 {
114   return put(Char(c));
115 }
116 
117 inline
118 OutputCharStream &OutputCharStream::operator<<(Newline)
119 {
120   put(Char(SP_LINE_TERM1));
121 #ifdef SP_LINE_TERM2
122   put(Char(SP_LINE_TERM2));
123 #endif
124   return *this;
125 }
126 
127 inline
128 OutputCharStream &OutputCharStream::operator<<(const StringC &str)
129 {
130   return write(str.data(), str.size());
131 }
132 
133 #ifdef SP_NAMESPACE
134 }
135 #endif
136 
137 #endif /* not OutputCharStream_INCLUDED */
138