iconv.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "iconv.h"
00023 #include "common.h"
00024 #include "error.h"
00025 #include "config.h"
00026 #include <errno.h>
00027 #include <string>
00028
00029 using namespace std;
00030
00031 namespace Barry {
00032
00033
00034
00035
00036 IConvHandle::IConvHandle(const char *fromcode, const char *tocode)
00037 {
00038 m_handle = iconv_open(tocode, fromcode);
00039 if( m_handle == (iconv_t)(-1) ) {
00040 throw ErrnoError(std::string("iconv_open failed: from ") + fromcode + " to " + tocode, errno);
00041 }
00042 }
00043
00044 IConvHandle::IConvHandle(const char *fromcode, const IConverter &ic)
00045 {
00046 m_handle = iconv_open(ic.m_tocode.c_str(), fromcode);
00047 if( m_handle == (iconv_t)(-1) ) {
00048 throw ErrnoError(std::string("iconv_open failed: from ") + fromcode + " to " + ic.m_tocode, errno);
00049 }
00050 }
00051
00052 IConvHandle::IConvHandle(const IConverter &ic, const char *tocode)
00053 {
00054 m_handle = iconv_open(tocode, ic.m_tocode.c_str());
00055 if( m_handle == (iconv_t)(-1) ) {
00056 throw ErrnoError(std::string("iconv_open failed: from ") + ic.m_tocode + " to " + tocode, errno);
00057 }
00058 }
00059
00060 IConvHandle::~IConvHandle()
00061 {
00062 iconv_close(m_handle);
00063 }
00064
00065
00066
00067
00068
00069 IConverter::IConverter(const char *tocode, bool throw_on_conv_err)
00070 : m_from(BLACKBERRY_CHARSET, tocode)
00071 , m_to(tocode, BLACKBERRY_CHARSET)
00072 , m_tocode(tocode)
00073 , m_throw_on_conv_err(throw_on_conv_err)
00074 {
00075 }
00076
00077 IConverter::~IConverter()
00078 {
00079 }
00080
00081 std::string IConverter::Convert(iconv_t cd, const std::string &str) const
00082 {
00083 size_t target = str.size() * 2;
00084 char *out = 0, *outstart = 0;
00085 size_t outbytesleft = 0;
00086 std::string ret;
00087
00088
00089
00090 for( int tries = 0; ; tries++ ) {
00091
00092 const char *in = str.data();
00093 size_t inbytesleft = str.size();
00094 out = outstart = (char*) m_buffer.GetBuffer(target);
00095 outbytesleft = m_buffer.GetBufSize();
00096
00097 iconv(cd, NULL, NULL, NULL, NULL);
00098 size_t status = iconv(cd, (ICONV_CONST char**) &in, &inbytesleft, &out, &outbytesleft);
00099
00100 if( status == (size_t)(-1) ) {
00101 if( errno == E2BIG && tries < 2 ) {
00102 target += inbytesleft * 2;
00103
00104 continue;
00105 }
00106
00107
00108
00109
00110
00111
00112 ErrnoError e(string("iconv failed with string '") + str + "'", errno);
00113 if( m_throw_on_conv_err ) {
00114 throw e;
00115 }
00116 else {
00117 cerr << e.what();
00118
00119 return str;
00120 }
00121 }
00122 else {
00123
00124 break;
00125 }
00126 }
00127
00128
00129 ret.assign(outstart, out - outstart);
00130 return ret;
00131 }
00132
00133 std::string IConverter::FromBB(const std::string &str) const
00134 {
00135 return Convert(m_from.m_handle, str);
00136 }
00137
00138 std::string IConverter::ToBB(const std::string &str) const
00139 {
00140 return Convert(m_to.m_handle, str);
00141 }
00142
00143 std::string IConverter::Convert(const IConvHandle &custom, const std::string &str) const
00144 {
00145 return Convert(custom.m_handle, str);
00146 }
00147
00148 }
00149