PageRenderTime 63ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/usr/src/cmd/man/src/util/nsgmls.src/lib/TranslateCodingSystem.cxx

https://bitbucket.org/0xffea/illumos-dccp
C++ | 210 lines | 187 code | 20 blank | 3 comment | 35 complexity | d2e8869dc87cde5ae2a8734127bcc31a MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-3.0, BSD-3-Clause, GPL-2.0, LGPL-2.1, LGPL-3.0, AGPL-1.0, GPL-3.0, 0BSD, BSD-2-Clause
  1. // Copyright (c) 1997 James Clark
  2. // See the file COPYING for copying permission.
  3. #pragma ident "%Z%%M% %I% %E% SMI"
  4. #include "splib.h"
  5. #include "TranslateCodingSystem.h"
  6. #include "types.h"
  7. #include "Owner.h"
  8. #ifdef SP_NAMESPACE
  9. namespace SP_NAMESPACE {
  10. #endif
  11. class TranslateDecoder : public Decoder {
  12. public:
  13. TranslateDecoder(Decoder *, const ConstPtr<CharMapResource<Char> > &);
  14. size_t decode(Char *, const char *, size_t, const char **);
  15. Boolean convertOffset(unsigned long &offset) const;
  16. private:
  17. Owner<Decoder> decoder_;
  18. ConstPtr<CharMapResource<Char> > map_;
  19. };
  20. TranslateDecoder::TranslateDecoder(Decoder *decoder,
  21. const ConstPtr<CharMapResource<Char> > &map)
  22. : Decoder(decoder->minBytesPerChar()), decoder_(decoder), map_(map)
  23. {
  24. }
  25. Boolean TranslateDecoder::convertOffset(unsigned long &offset) const
  26. {
  27. return decoder_->convertOffset(offset);
  28. }
  29. size_t TranslateDecoder::decode(Char *to, const char *s,
  30. size_t slen, const char **rest)
  31. {
  32. size_t n = decoder_->decode(to, s, slen, rest);
  33. for (size_t i = 0; i < n; i++)
  34. to[i] = (*map_)[to[i]];
  35. return n;
  36. }
  37. // FIXME set unencodeable handler for underlying encoder
  38. class TranslateEncoder : public RecoveringEncoder {
  39. public:
  40. TranslateEncoder(Encoder *, const ConstPtr<CharMapResource<Char> > &map,
  41. Char illegalChar);
  42. void output(const Char *, size_t, OutputByteStream *);
  43. void output(Char *, size_t, OutputByteStream *);
  44. void startFile(OutputByteStream *);
  45. private:
  46. Owner<Encoder> encoder_;
  47. ConstPtr<CharMapResource<Char> > map_;
  48. Char illegalChar_;
  49. enum { bufSize = 256 };
  50. Char buf_[bufSize];
  51. };
  52. TranslateEncoder::TranslateEncoder(Encoder *encoder,
  53. const ConstPtr<CharMapResource<Char> > &map,
  54. Char illegalChar)
  55. : encoder_(encoder), map_(map), illegalChar_(illegalChar)
  56. {
  57. }
  58. void TranslateEncoder::startFile(OutputByteStream *sbuf)
  59. {
  60. encoder_->startFile(sbuf);
  61. }
  62. void TranslateEncoder::output(const Char *s, size_t n, OutputByteStream *sbuf)
  63. {
  64. size_t j = 0;
  65. for (; n > 0; s++, n--) {
  66. Char c = (*map_)[*s];
  67. if (c == illegalChar_) {
  68. if (j > 0) {
  69. encoder_->output(buf_, j, sbuf);
  70. j = 0;
  71. }
  72. handleUnencodable(*s, sbuf);
  73. }
  74. else {
  75. if (j >= bufSize) {
  76. encoder_->output(buf_, j, sbuf);
  77. j = 0;
  78. }
  79. buf_[j++] = c;
  80. }
  81. }
  82. if (j > 0)
  83. encoder_->output(buf_, j, sbuf);
  84. }
  85. void TranslateEncoder::output(Char *s, size_t n, OutputByteStream *sbuf)
  86. {
  87. size_t i = 0;
  88. for (;;) {
  89. if (i == n) {
  90. if (n > 0)
  91. encoder_->output(s, n, sbuf);
  92. break;
  93. }
  94. Char c = (*map_)[s[i]];
  95. if (c == illegalChar_) {
  96. if (i > 0)
  97. encoder_->output(s, i, sbuf);
  98. handleUnencodable(s[i], sbuf);
  99. i++;
  100. s += i;
  101. n -= i;
  102. i = 0;
  103. }
  104. else
  105. s[i++] = c;
  106. }
  107. }
  108. TranslateCodingSystem::TranslateCodingSystem(const CodingSystem *sub,
  109. const Desc *desc,
  110. const CharsetInfo *charset,
  111. Char illegalChar,
  112. Char replacementChar)
  113. : sub_(sub),
  114. desc_(desc),
  115. charset_(charset),
  116. illegalChar_(illegalChar),
  117. replacementChar_(replacementChar)
  118. {
  119. }
  120. Decoder *TranslateCodingSystem::makeDecoder() const
  121. {
  122. if (decodeMap_.isNull()) {
  123. CharMapResource<Char> *map = new CharMapResource<Char>(replacementChar_);
  124. *(ConstPtr<CharMapResource<Char> > *)&decodeMap_ = map;
  125. for (const Desc *d = desc_; d->number != CharsetRegistry::UNREGISTERED; d++) {
  126. Owner<CharsetRegistry::Iter> iter(CharsetRegistry::makeIter(d->number));
  127. if (iter) {
  128. WideChar min;
  129. WideChar max;
  130. UnivChar univ;
  131. while (iter->next(min, max, univ)) {
  132. do {
  133. ISet<WideChar> set;
  134. WideChar sysChar;
  135. WideChar count;
  136. int n = charset_->univToDesc(univ, sysChar, set, count);
  137. if (count > (max - min) + 1)
  138. count = (max - min) + 1;
  139. if (n) {
  140. for (WideChar i = 0; i < count; i++)
  141. map->setChar(min + d->add + i, sysChar + i);
  142. }
  143. min += count - 1;
  144. univ += count;
  145. } while (min++ != max);
  146. }
  147. }
  148. }
  149. }
  150. return new TranslateDecoder(sub_->makeDecoder(), decodeMap_);
  151. }
  152. Encoder *TranslateCodingSystem::makeEncoder() const
  153. {
  154. if (encodeMap_.isNull()) {
  155. CharMapResource<Char> *map = new CharMapResource<Char>(illegalChar_);
  156. *(ConstPtr<CharMapResource<Char> > *)&encodeMap_ = map;
  157. for (const Desc *d = desc_; d->number != CharsetRegistry::UNREGISTERED; d++) {
  158. Owner<CharsetRegistry::Iter> iter(CharsetRegistry::makeIter(d->number));
  159. if (iter) {
  160. WideChar min;
  161. WideChar max;
  162. UnivChar univ;
  163. while (iter->next(min, max, univ)) {
  164. do {
  165. ISet<WideChar> set;
  166. WideChar sysChar;
  167. WideChar count;
  168. int n = charset_->univToDesc(univ, sysChar, set, count);
  169. if (count > (max - min) + 1)
  170. count = (max - min) + 1;
  171. if (n) {
  172. for (WideChar i = 0; i < count; i++)
  173. map->setChar(sysChar + i, min + d->add + i);
  174. }
  175. min += count - 1;
  176. univ += count;
  177. } while (min++ != max);
  178. }
  179. }
  180. }
  181. }
  182. return new TranslateEncoder(sub_->makeEncoder(), encodeMap_, illegalChar_);
  183. }
  184. unsigned TranslateCodingSystem::fixedBytesPerChar() const
  185. {
  186. return sub_->fixedBytesPerChar();
  187. }
  188. #ifdef SP_NAMESPACE
  189. }
  190. #endif