1- // ===-- TextEncoding.cpp - Encoding conversion class ----- ---------*- C++ -*-=//
1+ // ===-- TextEncoding.cpp - Text encoding conversion class ---------*- C++ -*-=//
22//
33// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44// See https://llvm.org/LICENSE.txt for license information.
@@ -82,7 +82,7 @@ enum ConversionType {
8282// aforementioned encodings. The use of tables for conversion is only
8383// possible because EBCDIC 1047 is a single-byte, stateless encoding; other
8484// encodings are not supported.
85- class TextEncodingConverterTable
85+ class TextEncodingConverterTable final
8686 : public details::TextEncodingConverterImplBase {
8787 const ConversionType ConvType;
8888
@@ -118,7 +118,8 @@ struct UConverterDeleter {
118118};
119119using UConverterUniquePtr = std::unique_ptr<UConverter, UConverterDeleter>;
120120
121- class TextEncodingConverterICU : public details ::TextEncodingConverterImplBase {
121+ class TextEncodingConverterICU final
122+ : public details::TextEncodingConverterImplBase {
122123 UConverterUniquePtr FromConvDesc;
123124 UConverterUniquePtr ToConvDesc;
124125
@@ -137,7 +138,8 @@ class TextEncodingConverterICU : public details::TextEncodingConverterImplBase {
137138// TODO: The current implementation discards the partial result and restarts the
138139// conversion from the beginning if there is a conversion error due to
139140// 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
141143std::error_code
142144TextEncodingConverterICU::convertString (StringRef Source,
143145 SmallVectorImpl<char > &Result) {
@@ -169,9 +171,12 @@ TextEncodingConverterICU::convertString(StringRef Source,
169171 /* pivotLimit=*/ NULL , /* reset=*/ true ,
170172 /* flush=*/ true , &EC);
171173 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 ());
175180 }
176181 // Some other error occured.
177182 Result.resize (Output - Result.data ());
@@ -190,7 +195,7 @@ void TextEncodingConverterICU::reset() {
190195}
191196
192197#elif HAVE_ICONV
193- class TextEncodingConverterIconv
198+ class TextEncodingConverterIconv final
194199 : public details::TextEncodingConverterImplBase {
195200 class UniqueIconvT {
196201 iconv_t ConvDesc;
@@ -230,7 +235,7 @@ class TextEncodingConverterIconv
230235// TODO: The current implementation discards the partial result and restarts the
231236// conversion from the beginning if there is a conversion error due to
232237// 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.
234239std::error_code
235240TextEncodingConverterIconv::convertString (StringRef Source,
236241 SmallVectorImpl<char > &Result) {
@@ -249,7 +254,7 @@ TextEncodingConverterIconv::convertString(StringRef Source,
249254 if (errno == E2BIG && Capacity < Result.max_size ()) {
250255 HandleOverflow (Capacity, Output, OutputLength, Result);
251256 // Reset converter
252- iconv (ConvDesc, nullptr , nullptr , nullptr , nullptr );
257+ reset ( );
253258 return std::error_code ();
254259 } else {
255260 // Some other error occured.
@@ -269,7 +274,7 @@ TextEncodingConverterIconv::convertString(StringRef Source,
269274 // Setup the input. Use nullptr to reset iconv state if input length is
270275 // zero.
271276 size_t InputLength = Source.size ();
272- char *Input = InputLength ? const_cast <char *>(Source.data ()) : nullptr ;
277+ char *Input = InputLength ? const_cast <char *>(Source.data ()) : " " ;
273278 Ret = iconv (ConvDesc, &Input, &InputLength, &Output, &OutputLength);
274279 if (Ret != 0 ) {
275280 if (auto EC = HandleError (Ret))
@@ -291,7 +296,7 @@ TextEncodingConverterIconv::convertString(StringRef Source,
291296 return std::error_code ();
292297}
293298
294- void TextEncodingConverterIconv::reset () {
299+ inline void TextEncodingConverterIconv::reset () {
295300 iconv (ConvDesc, nullptr , nullptr , nullptr , nullptr );
296301}
297302
@@ -311,7 +316,7 @@ TextEncodingConverter::create(TextEncoding CPFrom, TextEncoding CPTo) {
311316 else if (CPFrom == TextEncoding::IBM1047 && CPTo == TextEncoding::UTF8)
312317 Conversion = IBM1047ToUTF8;
313318 else
314- return std::error_code (errno, std::generic_category () );
319+ return std::make_error_code ( std::errc::invalid_argument );
315320
316321 return TextEncodingConverter (
317322 std::make_unique<TextEncodingConverterTable>(Conversion));
@@ -330,21 +335,20 @@ ErrorOr<TextEncodingConverter> TextEncodingConverter::create(StringRef From,
330335#if HAVE_ICU
331336 UErrorCode EC = U_ZERO_ERROR;
332337 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+
336341 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));
343347 return TextEncodingConverter (std::move (Converter));
344348#elif HAVE_ICONV
345349 iconv_t ConvDesc = iconv_open (To.str ().c_str (), From.str ().c_str ());
346350 if (ConvDesc == (iconv_t )-1 )
347- return std::error_code (errno, std::generic_category () );
351+ return std::make_error_code ( std::errc::invalid_argument );
348352 return TextEncodingConverter (
349353 std::make_unique<TextEncodingConverterIconv>(ConvDesc));
350354#else
0 commit comments