1 // Copyright (c) 1997 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident "%Z%%M% %I% %E% SMI"
7 #include "TranslateCodingSystem.h"
12 namespace SP_NAMESPACE
{
15 class TranslateDecoder
: public Decoder
{
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;
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
]];
46 // FIXME set unencodeable handler for underlying encoder
48 class TranslateEncoder
: public RecoveringEncoder
{
50 TranslateEncoder(Encoder
*, const ConstPtr
<CharMapResource
<Char
> > &map
,
52 void output(const Char
*, size_t, OutputByteStream
*);
53 void output(Char
*, size_t, OutputByteStream
*);
54 void startFile(OutputByteStream
*);
56 Owner
<Encoder
> encoder_
;
57 ConstPtr
<CharMapResource
<Char
> > map_
;
59 enum { bufSize
= 256 };
63 TranslateEncoder::TranslateEncoder(Encoder
*encoder
,
64 const ConstPtr
<CharMapResource
<Char
> > &map
,
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
)
78 for (; n
> 0; s
++, n
--) {
80 if (c
== illegalChar_
) {
82 encoder_
->output(buf_
, j
, sbuf
);
85 handleUnencodable(*s
, sbuf
);
89 encoder_
->output(buf_
, j
, sbuf
);
96 encoder_
->output(buf_
, j
, sbuf
);
99 void TranslateEncoder::output(Char
*s
, size_t n
, OutputByteStream
*sbuf
)
105 encoder_
->output(s
, n
, sbuf
);
108 Char c
= (*map_
)[s
[i
]];
109 if (c
== illegalChar_
) {
111 encoder_
->output(s
, i
, sbuf
);
112 handleUnencodable(s
[i
], sbuf
);
123 TranslateCodingSystem::TranslateCodingSystem(const CodingSystem
*sub
,
125 const CharsetInfo
*charset
,
127 Char replacementChar
)
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
));
147 while (iter
->next(min
, max
, univ
)) {
152 int n
= charset_
->univToDesc(univ
, sysChar
, set
, count
);
153 if (count
> (max
- min
) + 1)
154 count
= (max
- min
) + 1;
156 for (WideChar i
= 0; i
< count
; i
++)
157 map
->setChar(min
+ d
->add
+ i
, sysChar
+ i
);
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
));
180 while (iter
->next(min
, max
, univ
)) {
185 int n
= charset_
->univToDesc(univ
, sysChar
, set
, count
);
186 if (count
> (max
- min
) + 1)
187 count
= (max
- min
) + 1;
189 for (WideChar i
= 0; i
< count
; i
++)
190 map
->setChar(sysChar
+ i
, min
+ d
->add
+ i
);
194 } while (min
++ != max
);
199 return new TranslateEncoder(sub_
->makeEncoder(), encodeMap_
, illegalChar_
);
202 unsigned TranslateCodingSystem::fixedBytesPerChar() const
204 return sub_
->fixedBytesPerChar();