1
- // ===-- TextEncoding.cpp - Encoding conversion class ----- ---------*- C++ -*-=//
1
+ // ===-- TextEncoding.cpp - Text encoding conversion class ---------*- C++ -*-=//
2
2
//
3
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
4
// See https://llvm.org/LICENSE.txt for license information.
@@ -82,7 +82,7 @@ enum ConversionType {
82
82
// aforementioned encodings. The use of tables for conversion is only
83
83
// possible because EBCDIC 1047 is a single-byte, stateless encoding; other
84
84
// encodings are not supported.
85
- class TextEncodingConverterTable
85
+ class TextEncodingConverterTable final
86
86
: public details::TextEncodingConverterImplBase {
87
87
const ConversionType ConvType;
88
88
@@ -118,7 +118,8 @@ struct UConverterDeleter {
118
118
};
119
119
using UConverterUniquePtr = std::unique_ptr<UConverter, UConverterDeleter>;
120
120
121
- class TextEncodingConverterICU : public details ::TextEncodingConverterImplBase {
121
+ class TextEncodingConverterICU final
122
+ : public details::TextEncodingConverterImplBase {
122
123
UConverterUniquePtr FromConvDesc;
123
124
UConverterUniquePtr ToConvDesc;
124
125
@@ -137,7 +138,8 @@ class TextEncodingConverterICU : public details::TextEncodingConverterImplBase {
137
138
// TODO: The current implementation discards the partial result and restarts the
138
139
// conversion from the beginning if there is a conversion error due to
139
140
// insufficient buffer size. In the future, it would better to save the partial
140
- // result and redo the conversion for the remaining string.
141
+ // result and resume the conversion for the remaining string.
142
+ // TODO: Improve translation of ICU errors to error_code
141
143
std::error_code
142
144
TextEncodingConverterICU::convertString (StringRef Source,
143
145
SmallVectorImpl<char > &Result) {
@@ -169,9 +171,12 @@ TextEncodingConverterICU::convertString(StringRef Source,
169
171
/* pivotLimit=*/ NULL , /* reset=*/ true ,
170
172
/* flush=*/ true , &EC);
171
173
if (U_FAILURE (EC)) {
172
- if (EC == U_BUFFER_OVERFLOW_ERROR && Capacity < Result.max_size ()) {
173
- HandleOverflow (Capacity, Output, OutputLength, Result);
174
- continue ;
174
+ if (EC == U_BUFFER_OVERFLOW_ERROR) {
175
+ if (Capacity < Result.max_size ()) {
176
+ HandleOverflow (Capacity, Output, OutputLength, Result);
177
+ continue ;
178
+ } else
179
+ return std::error_code (E2BIG, std::generic_category ());
175
180
}
176
181
// Some other error occured.
177
182
Result.resize (Output - Result.data ());
@@ -190,7 +195,7 @@ void TextEncodingConverterICU::reset() {
190
195
}
191
196
192
197
#elif HAVE_ICONV
193
- class TextEncodingConverterIconv
198
+ class TextEncodingConverterIconv final
194
199
: public details::TextEncodingConverterImplBase {
195
200
class UniqueIconvT {
196
201
iconv_t ConvDesc;
@@ -230,7 +235,7 @@ class TextEncodingConverterIconv
230
235
// TODO: The current implementation discards the partial result and restarts the
231
236
// conversion from the beginning if there is a conversion error due to
232
237
// insufficient buffer size. In the future, it would better to save the partial
233
- // result and redo the conversion for the remaining string.
238
+ // result and resume the conversion for the remaining string.
234
239
std::error_code
235
240
TextEncodingConverterIconv::convertString (StringRef Source,
236
241
SmallVectorImpl<char > &Result) {
@@ -249,7 +254,7 @@ TextEncodingConverterIconv::convertString(StringRef Source,
249
254
if (errno == E2BIG && Capacity < Result.max_size ()) {
250
255
HandleOverflow (Capacity, Output, OutputLength, Result);
251
256
// Reset converter
252
- iconv (ConvDesc, nullptr , nullptr , nullptr , nullptr );
257
+ reset ( );
253
258
return std::error_code ();
254
259
} else {
255
260
// Some other error occured.
@@ -269,7 +274,7 @@ TextEncodingConverterIconv::convertString(StringRef Source,
269
274
// Setup the input. Use nullptr to reset iconv state if input length is
270
275
// zero.
271
276
size_t InputLength = Source.size ();
272
- char *Input = InputLength ? const_cast <char *>(Source.data ()) : nullptr ;
277
+ char *Input = InputLength ? const_cast <char *>(Source.data ()) : " " ;
273
278
Ret = iconv (ConvDesc, &Input, &InputLength, &Output, &OutputLength);
274
279
if (Ret != 0 ) {
275
280
if (auto EC = HandleError (Ret))
@@ -291,7 +296,7 @@ TextEncodingConverterIconv::convertString(StringRef Source,
291
296
return std::error_code ();
292
297
}
293
298
294
- void TextEncodingConverterIconv::reset () {
299
+ inline void TextEncodingConverterIconv::reset () {
295
300
iconv (ConvDesc, nullptr , nullptr , nullptr , nullptr );
296
301
}
297
302
@@ -311,7 +316,7 @@ TextEncodingConverter::create(TextEncoding CPFrom, TextEncoding CPTo) {
311
316
else if (CPFrom == TextEncoding::IBM1047 && CPTo == TextEncoding::UTF8)
312
317
Conversion = IBM1047ToUTF8;
313
318
else
314
- return std::error_code (errno, std::generic_category () );
319
+ return std::make_error_code ( std::errc::invalid_argument );
315
320
316
321
return TextEncodingConverter (
317
322
std::make_unique<TextEncodingConverterTable>(Conversion));
@@ -330,21 +335,20 @@ ErrorOr<TextEncodingConverter> TextEncodingConverter::create(StringRef From,
330
335
#if HAVE_ICU
331
336
UErrorCode EC = U_ZERO_ERROR;
332
337
UConverterUniquePtr FromConvDesc (ucnv_open (From.str ().c_str (), &EC));
333
- if (U_FAILURE (EC)) {
334
- return std::error_code (errno, std::generic_category () );
335
- }
338
+ if (U_FAILURE (EC))
339
+ return std::make_error_code ( std::errc::invalid_argument );
340
+
336
341
UConverterUniquePtr ToConvDesc (ucnv_open (To.str ().c_str (), &EC));
337
- if (U_FAILURE (EC)) {
338
- return std::error_code (errno, std::generic_category ());
339
- }
340
- std::unique_ptr<details::TextEncodingConverterImplBase> Converter =
341
- std::make_unique<TextEncodingConverterICU>(std::move (FromConvDesc),
342
- std::move (ToConvDesc));
342
+ if (U_FAILURE (EC))
343
+ return std::make_error_code (std::errc::invalid_argument);
344
+
345
+ auto Converter = std::make_unique<TextEncodingConverterICU>(
346
+ std::move (FromConvDesc), std::move (ToConvDesc));
343
347
return TextEncodingConverter (std::move (Converter));
344
348
#elif HAVE_ICONV
345
349
iconv_t ConvDesc = iconv_open (To.str ().c_str (), From.str ().c_str ());
346
350
if (ConvDesc == (iconv_t )-1 )
347
- return std::error_code (errno, std::generic_category () );
351
+ return std::make_error_code ( std::errc::invalid_argument );
348
352
return TextEncodingConverter (
349
353
std::make_unique<TextEncodingConverterIconv>(ConvDesc));
350
354
#else
0 commit comments