3065 some functions in the tcp module can be static
[unleashed.git] / usr / src / cmd / man / src / util / nsgmls.src / lib / TranslateCodingSystem.cxx
blobe71638eea5c90c938c7294aabbf9204019e1555e
1 // Copyright (c) 1997 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
5 #include "splib.h"
7 #include "TranslateCodingSystem.h"
8 #include "types.h"
9 #include "Owner.h"
11 #ifdef SP_NAMESPACE
12 namespace SP_NAMESPACE {
13 #endif
15 class TranslateDecoder : public Decoder {
16 public:
17 TranslateDecoder(Decoder *, const ConstPtr<CharMapResource<Char> > &);
18 size_t decode(Char *, const char *, size_t, const char **);
19 Boolean convertOffset(unsigned long &offset) const;
20 private:
21 Owner<Decoder> decoder_;
22 ConstPtr<CharMapResource<Char> > map_;
25 TranslateDecoder::TranslateDecoder(Decoder *decoder,
26 const ConstPtr<CharMapResource<Char> > &map)
27 : Decoder(decoder->minBytesPerChar()), decoder_(decoder), map_(map)
32 Boolean TranslateDecoder::convertOffset(unsigned long &offset) const
34 return decoder_->convertOffset(offset);
37 size_t TranslateDecoder::decode(Char *to, const char *s,
38 size_t slen, const char **rest)
40 size_t n = decoder_->decode(to, s, slen, rest);
41 for (size_t i = 0; i < n; i++)
42 to[i] = (*map_)[to[i]];
43 return n;
46 // FIXME set unencodeable handler for underlying encoder
48 class TranslateEncoder : public RecoveringEncoder {
49 public:
50 TranslateEncoder(Encoder *, const ConstPtr<CharMapResource<Char> > &map,
51 Char illegalChar);
52 void output(const Char *, size_t, OutputByteStream *);
53 void output(Char *, size_t, OutputByteStream *);
54 void startFile(OutputByteStream *);
55 private:
56 Owner<Encoder> encoder_;
57 ConstPtr<CharMapResource<Char> > map_;
58 Char illegalChar_;
59 enum { bufSize = 256 };
60 Char buf_[bufSize];
63 TranslateEncoder::TranslateEncoder(Encoder *encoder,
64 const ConstPtr<CharMapResource<Char> > &map,
65 Char illegalChar)
66 : encoder_(encoder), map_(map), illegalChar_(illegalChar)
70 void TranslateEncoder::startFile(OutputByteStream *sbuf)
72 encoder_->startFile(sbuf);
75 void TranslateEncoder::output(const Char *s, size_t n, OutputByteStream *sbuf)
77 size_t j = 0;
78 for (; n > 0; s++, n--) {
79 Char c = (*map_)[*s];
80 if (c == illegalChar_) {
81 if (j > 0) {
82 encoder_->output(buf_, j, sbuf);
83 j = 0;
85 handleUnencodable(*s, sbuf);
87 else {
88 if (j >= bufSize) {
89 encoder_->output(buf_, j, sbuf);
90 j = 0;
92 buf_[j++] = c;
95 if (j > 0)
96 encoder_->output(buf_, j, sbuf);
99 void TranslateEncoder::output(Char *s, size_t n, OutputByteStream *sbuf)
101 size_t i = 0;
102 for (;;) {
103 if (i == n) {
104 if (n > 0)
105 encoder_->output(s, n, sbuf);
106 break;
108 Char c = (*map_)[s[i]];
109 if (c == illegalChar_) {
110 if (i > 0)
111 encoder_->output(s, i, sbuf);
112 handleUnencodable(s[i], sbuf);
113 i++;
114 s += i;
115 n -= i;
116 i = 0;
118 else
119 s[i++] = c;
123 TranslateCodingSystem::TranslateCodingSystem(const CodingSystem *sub,
124 const Desc *desc,
125 const CharsetInfo *charset,
126 Char illegalChar,
127 Char replacementChar)
128 : sub_(sub),
129 desc_(desc),
130 charset_(charset),
131 illegalChar_(illegalChar),
132 replacementChar_(replacementChar)
136 Decoder *TranslateCodingSystem::makeDecoder() const
138 if (decodeMap_.isNull()) {
139 CharMapResource<Char> *map = new CharMapResource<Char>(replacementChar_);
140 *(ConstPtr<CharMapResource<Char> > *)&decodeMap_ = map;
141 for (const Desc *d = desc_; d->number != CharsetRegistry::UNREGISTERED; d++) {
142 Owner<CharsetRegistry::Iter> iter(CharsetRegistry::makeIter(d->number));
143 if (iter) {
144 WideChar min;
145 WideChar max;
146 UnivChar univ;
147 while (iter->next(min, max, univ)) {
148 do {
149 ISet<WideChar> set;
150 WideChar sysChar;
151 WideChar count;
152 int n = charset_->univToDesc(univ, sysChar, set, count);
153 if (count > (max - min) + 1)
154 count = (max - min) + 1;
155 if (n) {
156 for (WideChar i = 0; i < count; i++)
157 map->setChar(min + d->add + i, sysChar + i);
159 min += count - 1;
160 univ += count;
161 } while (min++ != max);
166 return new TranslateDecoder(sub_->makeDecoder(), decodeMap_);
169 Encoder *TranslateCodingSystem::makeEncoder() const
171 if (encodeMap_.isNull()) {
172 CharMapResource<Char> *map = new CharMapResource<Char>(illegalChar_);
173 *(ConstPtr<CharMapResource<Char> > *)&encodeMap_ = map;
174 for (const Desc *d = desc_; d->number != CharsetRegistry::UNREGISTERED; d++) {
175 Owner<CharsetRegistry::Iter> iter(CharsetRegistry::makeIter(d->number));
176 if (iter) {
177 WideChar min;
178 WideChar max;
179 UnivChar univ;
180 while (iter->next(min, max, univ)) {
181 do {
182 ISet<WideChar> set;
183 WideChar sysChar;
184 WideChar count;
185 int n = charset_->univToDesc(univ, sysChar, set, count);
186 if (count > (max - min) + 1)
187 count = (max - min) + 1;
188 if (n) {
189 for (WideChar i = 0; i < count; i++)
190 map->setChar(sysChar + i, min + d->add + i);
192 min += count - 1;
193 univ += count;
194 } while (min++ != max);
199 return new TranslateEncoder(sub_->makeEncoder(), encodeMap_, illegalChar_);
202 unsigned TranslateCodingSystem::fixedBytesPerChar() const
204 return sub_->fixedBytesPerChar();
207 #ifdef SP_NAMESPACE
209 #endif