SECURITY fix for dtappintegrate: Use mktemp(1) to generate a template.
[oweals/cde.git] / cde / programs / nsgmls / OutputCharStream.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: OutputCharStream.C /main/1 1996/07/29 16:59:34 cde-hp $ */
24 // Copyright (c) 1994 James Clark
25 // See the file COPYING for copying permission.
26
27 #include "splib.h"
28 #include "OutputCharStream.h"
29 #include "CodingSystem.h"
30 #include "macros.h"
31 #if defined(linux) || defined(CSRG_BASED)
32 #include <iostream>
33 #else
34 #include <iostream.h>
35 #endif
36 #include <stdio.h>
37
38 #ifdef SP_NAMESPACE
39 namespace SP_NAMESPACE {
40 #endif
41
42 OutputCharStream::OutputCharStream()
43 : ptr_(0), end_(0), escaper_(0)
44 {
45 }
46
47 OutputCharStream::~OutputCharStream()
48 {
49 }
50
51 OutputCharStream &OutputCharStream::write(const Char *s, size_t n)
52 {
53   for (;;) {
54     size_t spare = end_ - ptr_;
55     if (n <= spare) {
56       memcpy(ptr_, s, n*sizeof(Char));
57       ptr_ += n;
58       break;
59     }
60     if (spare > 0) {
61       memcpy(ptr_, s, spare*sizeof(Char));
62       ptr_ += spare;
63       s += spare;
64       n -= spare;
65     }
66     n--;
67     flushBuf(*s++);
68   }
69   return *this;
70 }
71
72 OutputCharStream &OutputCharStream::operator<<(const char *s)
73 {
74   while (*s)
75     put(*s++);
76   return *this;
77 }
78
79 // FIXME Avoid stdio
80
81 OutputCharStream &OutputCharStream::operator<<(unsigned long n)
82 {
83   char buf[sizeof(unsigned long)*3 + 1];
84   sprintf(buf, "%lu", n);
85   return *this << buf;
86 }
87
88 OutputCharStream &OutputCharStream::operator<<(int n)
89 {
90   char buf[sizeof(int)*3 + 2];
91   sprintf(buf, "%d", n);
92   return *this << buf;
93 }
94
95
96 IosOutputCharStream::IosOutputCharStream()
97 : buf_(0), byteStream_(0)
98 {
99 }
100
101 IosOutputCharStream::IosOutputCharStream(streambuf *byteStream,
102                                          const OutputCodingSystem *codingSystem)
103 : buf_(0),
104   byteStream_(byteStream),
105   ownedEncoder_(codingSystem->makeEncoder())
106 {
107   encoder_ = ownedEncoder_.pointer();
108   encoder_->setUnencodableHandler(this);
109   allocBuf(codingSystem->fixedBytesPerChar());
110   encoder_->startFile(byteStream_);
111 }
112
113 IosOutputCharStream::IosOutputCharStream(streambuf *byteStream,
114                                          Encoder *encoder)
115 : buf_(0),
116   byteStream_(byteStream),
117   encoder_(encoder)
118 {
119   allocBuf(0);
120 }
121
122 IosOutputCharStream::~IosOutputCharStream()
123 {
124   if (byteStream_)
125     flush();
126   delete [] buf_;
127 }
128
129 void IosOutputCharStream::open(streambuf *byteStream,
130                                const OutputCodingSystem *codingSystem)
131 {
132   if (byteStream_)
133     flush();
134   byteStream_ = byteStream;
135   ownedEncoder_ = codingSystem->makeEncoder();
136   encoder_ = ownedEncoder_.pointer();
137   encoder_->setUnencodableHandler(this);
138   delete [] buf_;
139   buf_ = 0;
140   ptr_ = end_ = buf_;
141   allocBuf(codingSystem->fixedBytesPerChar());
142   encoder_->startFile(byteStream_);
143 }
144
145 void IosOutputCharStream::flush()
146 {
147   if (ptr_ > buf_) {
148     encoder_->output(buf_, ptr_ - buf_, byteStream_);
149     ptr_ = buf_;
150   }
151 #if defined(linux) || defined(CSRG_BASED)
152   byteStream_->pubsync();
153 #else
154   byteStream_->sync();
155 #endif
156 }
157
158 void IosOutputCharStream::flushBuf(Char c)
159 {
160   ASSERT(buf_ != 0);
161   encoder_->output(buf_, ptr_ - buf_, byteStream_);
162   ptr_ = buf_;
163   *ptr_++ = c;
164 }
165
166 void IosOutputCharStream::allocBuf(int bytesPerChar)
167 {
168   const int blockSize = 1024;
169   size_t bufSize = bytesPerChar ? blockSize/bytesPerChar : blockSize;
170   ptr_ = buf_ = new Char[bufSize];
171   end_ = buf_ + bufSize;
172 }
173
174 void IosOutputCharStream::handleUnencodable(Char c, streambuf *)
175 {
176   IosOutputCharStream tem(byteStream_, encoder_);
177   escape(tem, c);
178 }
179
180 StrOutputCharStream::StrOutputCharStream()
181 : buf_(0), bufSize_(0)
182 {
183   sync(0);
184 }
185
186 StrOutputCharStream::~StrOutputCharStream()
187 {
188   delete [] buf_;
189 }
190
191 void StrOutputCharStream::extractString(StringC &str)
192 {
193   str.assign(buf_, ptr_ - buf_);
194   sync(0);
195 }
196
197 void StrOutputCharStream::flushBuf(Char c)
198 {
199   size_t used = ptr_ - buf_;
200   size_t oldSize = bufSize_;
201   bufSize_ = oldSize ? 2*oldSize : 10;
202   Char *oldBuf = buf_;
203   buf_ = new Char[bufSize_];
204   if (oldSize) {
205     memcpy(buf_, oldBuf, oldSize * sizeof(Char));
206     delete [] oldBuf;
207   }
208   sync(used);
209   *ptr_++ = c;
210 }
211
212 void StrOutputCharStream::flush()
213 {
214 }
215
216 void StrOutputCharStream::sync(size_t length)
217 {
218   ptr_ = buf_ + length;
219   end_ = buf_ + bufSize_;
220 }
221
222 RecordOutputCharStream::RecordOutputCharStream(OutputCharStream *os)
223 : os_(os)
224 {
225   ptr_ = buf_;
226   end_ = buf_ + bufSize_;
227 }
228
229 RecordOutputCharStream::~RecordOutputCharStream()
230 {
231   outputBuf();
232   delete os_;
233 }
234
235 void RecordOutputCharStream::flush()
236 {
237   outputBuf();
238   os_->flush();
239 }
240
241 void RecordOutputCharStream::flushBuf(Char c)
242 {
243   outputBuf();
244   *ptr_++ = c;
245 }
246
247 void RecordOutputCharStream::outputBuf()
248 {
249   Char *start = buf_;
250   Char *p = start;
251   while (p < ptr_) {
252     switch (*p) {
253     case '\r':                  // translate RE to newline
254       if (start < p)
255         os_->write(start, p - start);
256       start = ++p;
257       *os_ << newline;
258       break;
259     case '\n':                  // ignore RS
260       if (start < p)
261         os_->write(start, p - start);
262       start = ++p;
263       break;
264     default:
265       ++p;
266       break;
267     }
268   }
269   if (start < p)
270     os_->write(start, p - start);
271   ptr_ = buf_;
272   end_ = buf_ + bufSize_;
273 }
274
275 #ifdef SP_NAMESPACE
276 }
277 #endif