OutputCharStream.C 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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 libraries 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. #include "splib.h"
  27. #include "OutputCharStream.h"
  28. #include "CodingSystem.h"
  29. #include "macros.h"
  30. #if defined(__linux__) || defined(CSRG_BASED) || defined(sun)
  31. #include <iostream>
  32. #else
  33. #include <iostream.h>
  34. #endif
  35. #include <stdio.h>
  36. #ifdef SP_NAMESPACE
  37. namespace SP_NAMESPACE {
  38. #endif
  39. OutputCharStream::OutputCharStream()
  40. : ptr_(0), end_(0), escaper_(0)
  41. {
  42. }
  43. OutputCharStream::~OutputCharStream()
  44. {
  45. }
  46. OutputCharStream &OutputCharStream::write(const Char *s, size_t n)
  47. {
  48. for (;;) {
  49. size_t spare = end_ - ptr_;
  50. if (n <= spare) {
  51. memcpy(ptr_, s, n*sizeof(Char));
  52. ptr_ += n;
  53. break;
  54. }
  55. if (spare > 0) {
  56. memcpy(ptr_, s, spare*sizeof(Char));
  57. ptr_ += spare;
  58. s += spare;
  59. n -= spare;
  60. }
  61. n--;
  62. flushBuf(*s++);
  63. }
  64. return *this;
  65. }
  66. OutputCharStream &OutputCharStream::operator<<(const char *s)
  67. {
  68. while (*s)
  69. put(*s++);
  70. return *this;
  71. }
  72. // FIXME Avoid stdio
  73. OutputCharStream &OutputCharStream::operator<<(unsigned long n)
  74. {
  75. char buf[sizeof(unsigned long)*3 + 1];
  76. sprintf(buf, "%lu", n);
  77. return *this << buf;
  78. }
  79. OutputCharStream &OutputCharStream::operator<<(int n)
  80. {
  81. char buf[sizeof(int)*3 + 2];
  82. sprintf(buf, "%d", n);
  83. return *this << buf;
  84. }
  85. IosOutputCharStream::IosOutputCharStream()
  86. : buf_(0), byteStream_(0), encoder_(NULL)
  87. {
  88. }
  89. IosOutputCharStream::IosOutputCharStream(streambuf *byteStream,
  90. const OutputCodingSystem *codingSystem)
  91. : buf_(0),
  92. byteStream_(byteStream),
  93. ownedEncoder_(codingSystem->makeEncoder())
  94. {
  95. encoder_ = ownedEncoder_.pointer();
  96. encoder_->setUnencodableHandler(this);
  97. allocBuf(codingSystem->fixedBytesPerChar());
  98. encoder_->startFile(byteStream_);
  99. }
  100. IosOutputCharStream::IosOutputCharStream(streambuf *byteStream,
  101. Encoder *encoder)
  102. : buf_(0),
  103. byteStream_(byteStream),
  104. encoder_(encoder)
  105. {
  106. allocBuf(0);
  107. }
  108. IosOutputCharStream::~IosOutputCharStream()
  109. {
  110. if (byteStream_)
  111. flush();
  112. delete [] buf_;
  113. }
  114. void IosOutputCharStream::open(streambuf *byteStream,
  115. const OutputCodingSystem *codingSystem)
  116. {
  117. if (byteStream_)
  118. flush();
  119. byteStream_ = byteStream;
  120. ownedEncoder_ = codingSystem->makeEncoder();
  121. encoder_ = ownedEncoder_.pointer();
  122. encoder_->setUnencodableHandler(this);
  123. delete [] buf_;
  124. buf_ = 0;
  125. ptr_ = end_ = buf_;
  126. allocBuf(codingSystem->fixedBytesPerChar());
  127. encoder_->startFile(byteStream_);
  128. }
  129. void IosOutputCharStream::flush()
  130. {
  131. if (ptr_ > buf_) {
  132. encoder_->output(buf_, ptr_ - buf_, byteStream_);
  133. ptr_ = buf_;
  134. }
  135. #if defined(__linux__) || defined(CSRG_BASED) || defined(sun)
  136. byteStream_->pubsync();
  137. #else
  138. byteStream_->sync();
  139. #endif
  140. }
  141. void IosOutputCharStream::flushBuf(Char c)
  142. {
  143. ASSERT(buf_ != 0);
  144. encoder_->output(buf_, ptr_ - buf_, byteStream_);
  145. ptr_ = buf_;
  146. *ptr_++ = c;
  147. }
  148. void IosOutputCharStream::allocBuf(int bytesPerChar)
  149. {
  150. const int blockSize = 1024;
  151. size_t bufSize = bytesPerChar ? blockSize/bytesPerChar : blockSize;
  152. ptr_ = buf_ = new Char[bufSize];
  153. end_ = buf_ + bufSize;
  154. }
  155. void IosOutputCharStream::handleUnencodable(Char c, streambuf *)
  156. {
  157. IosOutputCharStream tem(byteStream_, encoder_);
  158. escape(tem, c);
  159. }
  160. StrOutputCharStream::StrOutputCharStream()
  161. : buf_(0), bufSize_(0)
  162. {
  163. sync(0);
  164. }
  165. StrOutputCharStream::~StrOutputCharStream()
  166. {
  167. delete [] buf_;
  168. }
  169. void StrOutputCharStream::extractString(StringC &str)
  170. {
  171. str.assign(buf_, ptr_ - buf_);
  172. sync(0);
  173. }
  174. void StrOutputCharStream::flushBuf(Char c)
  175. {
  176. size_t used = ptr_ - buf_;
  177. size_t oldSize = bufSize_;
  178. bufSize_ = oldSize ? 2*oldSize : 10;
  179. Char *oldBuf = buf_;
  180. buf_ = new Char[bufSize_];
  181. if (oldSize) {
  182. memcpy(buf_, oldBuf, oldSize * sizeof(Char));
  183. delete [] oldBuf;
  184. }
  185. sync(used);
  186. *ptr_++ = c;
  187. }
  188. void StrOutputCharStream::flush()
  189. {
  190. }
  191. void StrOutputCharStream::sync(size_t length)
  192. {
  193. ptr_ = buf_ + length;
  194. end_ = buf_ + bufSize_;
  195. }
  196. RecordOutputCharStream::RecordOutputCharStream(OutputCharStream *os)
  197. : os_(os)
  198. {
  199. ptr_ = buf_;
  200. end_ = buf_ + bufSize_;
  201. }
  202. RecordOutputCharStream::~RecordOutputCharStream()
  203. {
  204. outputBuf();
  205. delete os_;
  206. }
  207. void RecordOutputCharStream::flush()
  208. {
  209. outputBuf();
  210. os_->flush();
  211. }
  212. void RecordOutputCharStream::flushBuf(Char c)
  213. {
  214. outputBuf();
  215. *ptr_++ = c;
  216. }
  217. void RecordOutputCharStream::outputBuf()
  218. {
  219. Char *start = buf_;
  220. Char *p = start;
  221. while (p < ptr_) {
  222. switch (*p) {
  223. case '\r': // translate RE to newline
  224. if (start < p)
  225. os_->write(start, p - start);
  226. start = ++p;
  227. *os_ << newline;
  228. break;
  229. case '\n': // ignore RS
  230. if (start < p)
  231. os_->write(start, p - start);
  232. start = ++p;
  233. break;
  234. default:
  235. ++p;
  236. break;
  237. }
  238. }
  239. if (start < p)
  240. os_->write(start, p - start);
  241. ptr_ = buf_;
  242. end_ = buf_ + bufSize_;
  243. }
  244. #ifdef SP_NAMESPACE
  245. }
  246. #endif