PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/jade_1_2/jade/lib/TranslateCodingSystem.cxx

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