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

Reply via email to