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 <errno.h>
00026
00027 namespace Barry {
00028
00029 IConverter::IConverter(const char *tocode, bool throw_on_conv_err)
00030 : m_throw_on_conv_err(throw_on_conv_err)
00031 {
00032 m_from = iconv_open(tocode, BLACKBERRY_CHARSET);
00033 if( m_from == (iconv_t)(-1) ) {
00034 throw ErrnoError("iconv_open failed (from)", errno);
00035 }
00036
00037 m_to = iconv_open(BLACKBERRY_CHARSET, tocode);
00038 if( m_to == (iconv_t)(-1) ) {
00039 ErrnoError err("iconv_open failed (to)", errno);
00040 iconv_close(m_from);
00041 throw err;
00042 }
00043 }
00044
00045 IConverter::~IConverter()
00046 {
00047 iconv_close(m_from);
00048 iconv_close(m_to);
00049 }
00050
00051 std::string IConverter::Convert(iconv_t cd, const std::string &str) const
00052 {
00053 size_t target = str.size() * 2;
00054 char *out = 0, *outstart = 0;
00055 size_t outbytesleft = 0;
00056 std::string ret;
00057
00058
00059
00060 for( int tries = 0; ; tries++ ) {
00061
00062 const char *in = str.data();
00063 size_t inbytesleft = str.size();
00064 out = outstart = (char*) m_buffer.GetBuffer(target);
00065 outbytesleft = m_buffer.GetBufSize();
00066
00067 iconv(cd, NULL, NULL, NULL, NULL);
00068 size_t status = iconv(cd, (char**)&in, &inbytesleft, &out, &outbytesleft);
00069
00070 if( status == (size_t)(-1) ) {
00071 if( errno == E2BIG && tries < 2 ) {
00072 target += inbytesleft * 2;
00073
00074 continue;
00075 }
00076
00077
00078
00079
00080
00081
00082 if( m_throw_on_conv_err ) {
00083 throw ErrnoError("iconv failed", errno);
00084 }
00085 }
00086 else {
00087
00088 break;
00089 }
00090 }
00091
00092
00093 ret.assign(outstart, out - outstart);
00094 return ret;
00095 }
00096
00097 std::string IConverter::FromBB(const std::string &str) const
00098 {
00099 return Convert(m_from, str);
00100 }
00101
00102 std::string IConverter::ToBB(const std::string &str) const
00103 {
00104 return Convert(m_to, str);
00105 }
00106
00107 }
00108