Date: Tuesday, January 16, 2007 @ 19:13:16
Author: marc
Path: /cvsroot/carob/carob
Modified: include/StringCodecs.hpp (1.20 -> 1.21) src/Common.cpp (1.59 ->
1.60) src/StringCodecs.cpp (1.15 -> 1.16)
Reworked CAROB-79 iconv codec: simplified it by making it non-mutable.
Locks for non-thread safe iconv descriptors are no more static but
class members.
--------------------------+
include/StringCodecs.hpp | 31 ++++++-------------------
src/Common.cpp | 2 -
src/StringCodecs.cpp | 55 +++++++++++++--------------------------------
3 files changed, 26 insertions(+), 62 deletions(-)
Index: carob/include/StringCodecs.hpp
diff -u carob/include/StringCodecs.hpp:1.20 carob/include/StringCodecs.hpp:1.21
--- carob/include/StringCodecs.hpp:1.20 Thu Jan 11 10:37:17 2007
+++ carob/include/StringCodecs.hpp Tue Jan 16 19:13:16 2007
@@ -29,6 +29,7 @@
#ifdef CAROB_USE_ICONV
#include <iconv.h>
+#include <CriticalSection.hpp>
#endif
namespace CarobNS {
@@ -125,15 +126,10 @@
{
public:
/**
- * Default constructor.
- */
- IconvCodec();
-
- /**
* Constructor.
* @param code The character code from/to the conversion will be.
*/
- IconvCodec(const std::string &code);
+ IconvCodec(const std::string &code) throw (CodecException);
/**
* Destructor.
@@ -141,38 +137,26 @@
~IconvCodec();
/**
- * Set the character code from/to the conversion will be.
- * @param code The character code from/to the conversion will be.
- * @return true if succesfull
- * false for invalid character codes.
- */
- bool set_code(const std::string &code);
-
- /**
* Encode from wstring to string.
* @param w the wstring.
* @return a string.
*/
- std::string encode(const std::wstring&) const throw (CodecException);
+ std::string encode(const std::wstring&) throw (CodecException);
/**
* Decode from string to wstring.
* @param s the string.
* @return a wstring.
*/
- std::wstring decode(const std::string&) const throw (CodecException);
-
-private:
- /**
- * Close the conversion descriptors
- */
- void close();
+ std::wstring decode(const std::string&) throw (CodecException);
private:
/**
* the conversion descriptors
*/
iconv_t cd_from, cd_to;
+ /** iconv descriptors are stateful/not thread-safe */
+ CriticalSection iconvDecodeCS, iconvEncodeCS;
};
#endif // CAROB_USE_ICONV
@@ -215,7 +199,8 @@
static const CarobNS::MBSCodec ascii_codec;
/** Codec for UTF-8 strings */
#ifdef CAROB_USE_ICONV
- static const CarobNS::IconvCodec utf8_codec;
+ // iconv is stateful/not thread-safe: such codecs can't be "const"
+ static CarobNS::IconvCodec utf8_codec;
#else
static const CarobNS::MBSCodec utf8_codec;
#endif
Index: carob/src/Common.cpp
diff -u carob/src/Common.cpp:1.59 carob/src/Common.cpp:1.60
--- carob/src/Common.cpp:1.59 Thu Jan 11 11:34:43 2007
+++ carob/src/Common.cpp Tue Jan 16 19:13:16 2007
@@ -359,7 +359,7 @@
// call user_codec
const CarobNS::MBSCodec CarobNS::StaticCodecs::user_codec(tryuserlocale());
#ifdef CAROB_USE_ICONV
-const CarobNS::IconvCodec CarobNS::StaticCodecs::utf8_codec("UTF-8");
+CarobNS::IconvCodec CarobNS::StaticCodecs::utf8_codec("UTF-8");
#else
const CarobNS::MBSCodec CarobNS::StaticCodecs::utf8_codec(tryUTF8locale());
#endif
Index: carob/src/StringCodecs.cpp
diff -u carob/src/StringCodecs.cpp:1.15 carob/src/StringCodecs.cpp:1.16
--- carob/src/StringCodecs.cpp:1.15 Thu Jan 11 10:37:17 2007
+++ carob/src/StringCodecs.cpp Tue Jan 16 19:13:16 2007
@@ -171,65 +171,43 @@
#include <errno.h>
-#include <CriticalSection.hpp>
-
-namespace {
- CriticalSection iconvDecodeCS, iconvEncodeCS;
-}
-
-IconvCodec::IconvCodec() : cd_from(iconv_t(-1)), cd_to(iconv_t(-1))
-{
-}
-
-IconvCodec::IconvCodec(const std::string &code) : cd_from(iconv_t(-1)),
cd_to(iconv_t(-1))
-{
- if (!set_code(code))
- throw CodecException(L"Missing encodings.");
-}
-
-IconvCodec::~IconvCodec()
-{
- close();
-}
-
-bool
-IconvCodec::set_code(const std::string &code)
+IconvCodec::IconvCodec(const std::string &code) throw (CodecException)
{
- close();
cd_from = iconv_open(code.c_str(), "WCHAR_T");
+ if (cd_from == (iconv_t) -1)
+ throw CodecException(L"Failed to open iconv encoder to " +
fromString(code));
+
cd_to = iconv_open("WCHAR_T", code.c_str());
- return ((cd_from != iconv_t(-1)) && (cd_to != iconv_t(-1)));
+ if (cd_to == (iconv_t) -1)
+ throw CodecException(L"Failed to open iconv decoder from " +
fromString(code));
}
-void
-IconvCodec::close()
+IconvCodec::~IconvCodec()
{
- if (cd_from != iconv_t(-1))
{
+ LockScope ls(&iconvEncodeCS);
iconv_close(cd_from);
- cd_from = iconv_t(-1);
}
-
- if (cd_to != iconv_t(-1))
{
+ LockScope ls(&iconvDecodeCS);
iconv_close(cd_to);
- cd_to = iconv_t(-1);
}
}
std::wstring
-IconvCodec::decode(const std::string &s) const throw (CodecException)
+IconvCodec::decode(const std::string &s) throw (CodecException)
{
if (s.empty())
return std::wstring();
-
- LockScope ls(&iconvDecodeCS);
std::wstring result;
const char *inbuf = s.data();
size_t inbytesleft = s.length();
+ // lock the iconv descriptor
+ LockScope ls(&iconvDecodeCS);
+
// reset the state
if (iconv_const_adapter(iconv, cd_to, 0, 0, 0, 0) == (size_t) -1)
throw CodecException(L"iconv reset failed.");
@@ -266,13 +244,11 @@
}
std::string
-IconvCodec::encode(const std::wstring &w) const throw (CodecException)
+IconvCodec::encode(const std::wstring &w) throw (CodecException)
{
if (w.empty())
return std::string();
- LockScope ls(&iconvEncodeCS);
-
std::string result;
const char *inbuf = reinterpret_cast<const char *>(w.data());
@@ -281,6 +257,9 @@
char convertbuf[CONVERTER_BUFFER_SIZE];
char *outbuf;
size_t outbytesleft;
+
+ // lock the iconv descriptor
+ LockScope ls(&iconvEncodeCS);
// reset the state
if (iconv_const_adapter(iconv, cd_from, 0, 0, 0, 0) == (size_t) -1)
_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits