Only include character encodings actually supported by the iconv implementation used in the list returned from GetEncodingsList

Originally committed to SVN as r6026.
This commit is contained in:
Thomas Goyne 2011-12-22 21:13:39 +00:00
parent ebde064cb4
commit b29606759a
2 changed files with 29 additions and 15 deletions

View file

@ -431,5 +431,13 @@ size_t IconvWrapper::SrcStrLen(const char* str) {
size_t IconvWrapper::DstStrLen(const char* str) { size_t IconvWrapper::DstStrLen(const char* str) {
return mbstrlen(str, toNulLen); return mbstrlen(str, toNulLen);
} }
bool IsConversionSupported(const char *src, const char *dst) {
iconv_t cd = iconv_open(dst, src);
bool supported = cd != iconv_invalid;
iconv_close(cd);
return supported;
}
} }
} }

View file

@ -22,12 +22,12 @@
#ifndef LAGI_PRE #ifndef LAGI_PRE
#include <cstring> #include <cstring>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#endif #endif
#include <libaegisub/exception.h> #include <libaegisub/exception.h>
#include <libaegisub/scoped_ptr.h>
namespace agi { namespace agi {
namespace charset { namespace charset {
@ -39,21 +39,9 @@ DEFINE_SIMPLE_EXCEPTION_NOINNER(BufferTooSmall, ConversionFailure, "iconv/failed
DEFINE_SIMPLE_EXCEPTION_NOINNER(BadInput, ConversionFailure, "iconv/failed/EILSEQ") DEFINE_SIMPLE_EXCEPTION_NOINNER(BadInput, ConversionFailure, "iconv/failed/EILSEQ")
DEFINE_SIMPLE_EXCEPTION_NOINNER(BadOutput, ConversionFailure, "iconv/failed/EINVAL") DEFINE_SIMPLE_EXCEPTION_NOINNER(BadOutput, ConversionFailure, "iconv/failed/EINVAL")
/// @brief Get a list of support encodings with user-friendly names
template<class T>
T const& GetEncodingsList() {
static T nameList;
if (nameList.empty()) {
# define ADD(pretty, real) nameList.push_back(pretty)
# include <libaegisub/charsets.def>
# undef ADD
}
return nameList;
}
typedef void* iconv_t; typedef void* iconv_t;
// Helper class that abstracts away the differences betwen libiconv and // Helper class that abstracts away the differences between libiconv and
// POSIX iconv implementations // POSIX iconv implementations
class Converter; class Converter;
@ -61,7 +49,7 @@ class Converter;
class IconvWrapper { class IconvWrapper {
size_t toNulLen; size_t toNulLen;
size_t fromNulLen; size_t fromNulLen;
std::auto_ptr<Converter> conv; agi::scoped_ptr<Converter> conv;
public: public:
/// @brief Create a converter /// @brief Create a converter
@ -103,5 +91,23 @@ public:
size_t DstStrLen(const char* str); size_t DstStrLen(const char* str);
}; };
/// Is the conversion from src to dst supported by the linked iconv library?
/// @param src Source encoding name
/// @param dst Destination encoding name
/// @return false if either charset is not supported or the conversion cannot be done directly, true otherwise
bool IsConversionSupported(const char *src, const char *dst);
/// Get a list of supported encodings with user-friendly names
template<class T>
T const& GetEncodingsList() {
static T name_list;
if (name_list.empty()) {
# define ADD(pretty, real) if (IsConversionSupported(real, "utf-8")) name_list.push_back(pretty)
# include <libaegisub/charsets.def>
# undef ADD
}
return name_list;
}
} }
} }