From 4a09b0b10cbea1fdcb16161583ee22f7d151784b Mon Sep 17 00:00:00 2001 From: Martin Corino Date: Fri, 3 Aug 2018 14:15:38 +0200 Subject: add full support for streaming std::(w)string (optimized for C++11 and onwards) added tests for optimized std::(w)string support extend character translators with std::(w)string support also --- ACE/ace/CDR_Size.h | 10 ++ ACE/ace/CDR_Size.inl | 36 +++++++ ACE/ace/CDR_Stream.cpp | 164 +++++++++++++++++++++++++++++ ACE/ace/CDR_Stream.h | 79 ++++++++++++++ ACE/ace/CDR_Stream.inl | 131 +++++++++++++++++++++++ ACE/ace/Codeset_IBM1047.cpp | 72 +++++++++++++ ACE/ace/Codeset_IBM1047.h | 4 + ACE/tests/CDR_Test.cpp | 80 ++++++++++++++ TAO/tao/CDR.h | 27 ++--- TAO/tao/CDR.inl | 72 +++++++------ TAO/tao/Codeset/UTF16_BOM_Translator.cpp | 68 ++++++++++++ TAO/tao/Codeset/UTF16_BOM_Translator.h | 4 + TAO/tao/Codeset/UTF8_Latin1_Translator.cpp | 49 +++++++++ TAO/tao/Codeset/UTF8_Latin1_Translator.h | 2 + 14 files changed, 747 insertions(+), 51 deletions(-) diff --git a/ACE/ace/CDR_Size.h b/ACE/ace/CDR_Size.h index 0a29edf58a1..a791b89bd64 100644 --- a/ACE/ace/CDR_Size.h +++ b/ACE/ace/CDR_Size.h @@ -78,6 +78,10 @@ public: ACE_CDR::Boolean write_wstring (const ACE_CDR::WChar *x); ACE_CDR::Boolean write_wstring (ACE_CDR::ULong length, const ACE_CDR::WChar *x); + ACE_CDR::Boolean write_string (const std::string &x); +#if !defined(ACE_LACKS_STD_WSTRING) + ACE_CDR::Boolean write_wstring (const std::wstring &x); +#endif //@} /// @note the portion written starts at and ends @@ -223,6 +227,12 @@ extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, const ACE_CDR::Char* x); extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, const ACE_CDR::WChar* x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + const std::string& x); +#if !defined(ACE_LACKS_STD_WSTRING) +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + const std::wstring& x); +#endif ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ACE/ace/CDR_Size.inl b/ACE/ace/CDR_Size.inl index 9b83b6f72e0..d138b3de13b 100644 --- a/ACE/ace/CDR_Size.inl +++ b/ACE/ace/CDR_Size.inl @@ -143,6 +143,26 @@ ACE_SizeCDR::write_wstring (const ACE_CDR::WChar *x) return this->write_wstring (0, 0); } +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_string (const std::string &x) +{ + ACE_CDR::ULong len = + static_cast (x.size ()); + return this->write_string (len, + x.empty () ? 0 : x.c_str ()); +} + +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_wstring (const std::wstring &x) +{ + ACE_CDR::ULong len = + static_cast (x.size ()); + return this->write_wstring (len, + x.empty () ? 0 : x.c_str ()); +} +#endif + ACE_INLINE ACE_CDR::Boolean ACE_SizeCDR::write_char_array (const ACE_CDR::Char *x, ACE_CDR::ULong length) @@ -372,6 +392,22 @@ operator<< (ACE_SizeCDR &ss, const ACE_CDR::WChar *x) return (ACE_CDR::Boolean) ss.good_bit (); } +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, const std::string& x) +{ + ss.write_string (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, const std::wstring& x) +{ + ss.write_wstring (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} +#endif + // The following use the helper classes ACE_INLINE ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_boolean x) diff --git a/ACE/ace/CDR_Stream.cpp b/ACE/ace/CDR_Stream.cpp index 3df331ff80b..32654aeddf8 100644 --- a/ACE/ace/CDR_Stream.cpp +++ b/ACE/ace/CDR_Stream.cpp @@ -1684,6 +1684,146 @@ ACE_InputCDR::read_wstring (ACE_CDR::WChar*& x) return false; } +// As of C++11 std::string guarantees contiguous memory storage. +// That provides the opportunity to optimize CDR streaming. +ACE_CDR::Boolean +ACE_InputCDR::read_string (std::string& x) +{ +#if defined (ACE_HAS_CPP11) + // @@ This is a slight violation of "Optimize for the common case", + // i.e. normally the translator will be 0, but OTOH the code is + // smaller and should be better for the cache ;-) ;-) + if (this->char_translator_ != 0) + { + this->good_bit_ = this->char_translator_->read_string (*this, x); + return this->good_bit_; + } + + ACE_CDR::ULong len = 0; + + if (!this->read_ulong (len)) + return false; + + // A check for the length being too great is done later in the + // call to read_char_array but we want to have it done before + // the memory is allocated. + if (len > 0 && len <= this->length()) + { + try + { + x.resize (len-1); // no need to include the terminating '\0' here + } + catch (const std::bad_alloc&) + { + return false; + } + + if (len == 0 || this->read_char_array (&x[0], len-1)) + { + return this->skip_char (); // skip the terminating '\0' + } + } + + this->good_bit_ = false; + x.clear (); + return false; +#else + ACE_CDR::Char *buf = 0; + ACE_CDR::Boolean const marshal_flag = this->read_string (buf); + x.assign (buf); + ACE::strdelete (buf); + return marshal_flag; +#endif +} + +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_CDR::Boolean +ACE_InputCDR::read_wstring (std::wstring& x) +{ +#if defined (ACE_HAS_CPP11) + // @@ This is a slight violation of "Optimize for the common case", + // i.e. normally the translator will be 0, but OTOH the code is + // smaller and should be better for the cache ;-) ;-) + if (this->wchar_translator_ != 0) + { + this->good_bit_ = this->wchar_translator_->read_wstring (*this, x); + return this->good_bit_; + } + if (ACE_OutputCDR::wchar_maxbytes_ == 0) + { + errno = EACCES; + return (this->good_bit_ = false); + } + + ACE_CDR::ULong len = 0; + + if (!this->read_ulong (len)) + { + return false; + } + + // A check for the length being too great is done later in the + // call to read_char_array but we want to have it done before + // the memory is allocated. + if (len > 0 && len <= this->length ()) + { + if (static_cast (this->major_version_) == 1 + && static_cast (this->minor_version_) == 2) + { + len /= + ACE_Utils::truncate_cast ( + ACE_OutputCDR::wchar_maxbytes_); + + try + { + x.resize (len); + } + catch (const std::bad_alloc&) + { + return false; + } + + if (this->read_wchar_array (&x[0], len)) + { + return true; + } + } + else + { + try + { + x.resize (len-1); // no need to include the terminating '\0' here + } + catch (const std::bad_alloc&) + { + return false; + } + + if (len == 1 || this->read_wchar_array (&x[0], len-1)) + { + return this->skip_wchar (); // skip the terminating '\0' + } + } + } + else if (len == 0) + { + x.clear (); + return true; + } + + this->good_bit_ = false; + x.clear (); + return false; +#else + ACE_CDR::WChar *buf = 0; + ACE_CDR::Boolean const marshal_flag = this->read_wstring (buf); + x.assign (buf); + ACE::strdelete (buf); + return marshal_flag; +#endif +} +#endif + ACE_CDR::Boolean ACE_InputCDR::read_array (void* x, size_t size, @@ -2227,12 +2367,36 @@ ACE_Char_Codeset_Translator::~ACE_Char_Codeset_Translator (void) { } +ACE_CDR::Boolean +ACE_Char_Codeset_Translator::read_string (ACE_InputCDR &cdr, + std::string &x) +{ + ACE_CDR::Char *buf = 0; + ACE_CDR::Boolean const marshal_flag = this->read_string (cdr, buf); + x.assign (buf); + ACE::strdelete (buf); + return marshal_flag; +} + // -------------------------------------------------------------- ACE_WChar_Codeset_Translator::~ACE_WChar_Codeset_Translator (void) { } +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_CDR::Boolean +ACE_WChar_Codeset_Translator::read_wstring (ACE_InputCDR &cdr, + std::wstring &x) +{ + ACE_CDR::WChar *buf = 0; + ACE_CDR::Boolean const marshal_flag = this->read_wstring (cdr, buf); + x.assign (buf); + ACE::strdelete (buf); + return marshal_flag; +} +#endif + // -------------------------------------------------------------- ACE_CDR::Boolean diff --git a/ACE/ace/CDR_Stream.h b/ACE/ace/CDR_Stream.h index d085fb2ccd1..42f9bd7af1a 100644 --- a/ACE/ace/CDR_Stream.h +++ b/ACE/ace/CDR_Stream.h @@ -221,6 +221,24 @@ public: ACE_CDR::ULong bound_; ACE_CDR::Boolean nocopy_; }; + + struct ACE_Export from_std_string + { + from_std_string (const std::string &s, + ACE_CDR::ULong b); + const std::string &val_; + ACE_CDR::ULong bound_; + }; + +#if !defined(ACE_LACKS_STD_WSTRING) + struct ACE_Export from_std_wstring + { + from_std_wstring (const std::wstring &ws, + ACE_CDR::ULong b); + const std::wstring &val_; + ACE_CDR::ULong bound_; + }; +#endif //@} /** @@ -250,6 +268,11 @@ public: ACE_CDR::Boolean write_wstring (const ACE_CDR::WChar *x); ACE_CDR::Boolean write_wstring (ACE_CDR::ULong length, const ACE_CDR::WChar *x); + ACE_CDR::Boolean write_string (const std::string &x); +#if !defined(ACE_LACKS_STD_WSTRING) + ACE_CDR::Boolean write_wstring (const std::wstring &x); +#endif + //@} /// @note the portion written starts at @a x and ends @@ -794,6 +817,25 @@ public: const ACE_CDR::WChar *&val_; ACE_CDR::ULong bound_; }; + + /// Helper classes for extracting bounded strings into std::string/wstring. + struct ACE_Export to_std_string + { + to_std_string (std::string &s, + ACE_CDR::ULong b); + std::string &val_; + ACE_CDR::ULong bound_; + }; + +#if !defined(ACE_LACKS_STD_WSTRING) + struct ACE_Export to_std_wstring + { + to_std_wstring (std::wstring &ws, + ACE_CDR::ULong b); + std::wstring &val_; + ACE_CDR::ULong bound_; + }; +#endif /* ACE_LACKS_STD_WSTRING */ //@} /** @@ -818,6 +860,10 @@ public: ACE_CDR::Boolean read_string (ACE_CDR::Char *&x); ACE_CDR::Boolean read_string (ACE_CString &x); ACE_CDR::Boolean read_wstring (ACE_CDR::WChar*& x); + ACE_CDR::Boolean read_string (std::string& x); +#if !defined(ACE_LACKS_STD_WSTRING) + ACE_CDR::Boolean read_wstring (std::wstring& x); +#endif //@} /** @@ -1114,6 +1160,12 @@ public: virtual ACE_CDR::Boolean read_string (ACE_InputCDR&, ACE_CDR::Char *&) = 0; + /// Read a std::string from the stream, including the length, converting + /// the characters from the stream codeset to the native codeset + /// (provide non-optimized default implementation) + virtual ACE_CDR::Boolean read_string (ACE_InputCDR&, + std::string &); + /// Read an array of characters from the stream, converting the /// characters from the stream codeset to the native codeset. virtual ACE_CDR::Boolean read_char_array (ACE_InputCDR&, @@ -1210,6 +1262,13 @@ public: ACE_CDR::WChar&) = 0; virtual ACE_CDR::Boolean read_wstring (ACE_InputCDR&, ACE_CDR::WChar *&) = 0; +#if !defined(ACE_LACKS_STD_WSTRING) + /// Read a std::wstring from the stream, including the length, converting + /// the characters from the stream codeset to the native codeset + /// (provide non-optimized default implementation) + virtual ACE_CDR::Boolean read_wstring (ACE_InputCDR&, + std::wstring &); +#endif virtual ACE_CDR::Boolean read_wchar_array (ACE_InputCDR&, ACE_CDR::WChar*, ACE_CDR::ULong) = 0; @@ -1344,6 +1403,16 @@ extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, const ACE_CDR::Char* x); extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, const ACE_CDR::WChar* x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_OutputCDR::from_std_string x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + const std::string& x); +#if !defined(ACE_LACKS_STD_WSTRING) +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + ACE_OutputCDR::from_std_wstring x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, + const std::wstring& x); +#endif // Not used by CORBA or TAO extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, @@ -1389,6 +1458,16 @@ extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, ACE_CDR::Char*& x); extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, ACE_CDR::WChar*& x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_InputCDR &os, + ACE_InputCDR::to_std_string x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + std::string& x); +#if !defined(ACE_LACKS_STD_WSTRING) +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_InputCDR &os, + ACE_InputCDR::to_std_wstring x); +extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is, + std::wstring& x); +#endif ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ACE/ace/CDR_Stream.inl b/ACE/ace/CDR_Stream.inl index 85c5f132d03..fe25108da85 100644 --- a/ACE/ace/CDR_Stream.inl +++ b/ACE/ace/CDR_Stream.inl @@ -127,6 +127,40 @@ ACE_InputCDR::to_wstring::to_wstring (const ACE_CDR::WChar *&ws, { } +ACE_INLINE +ACE_InputCDR::to_std_string::to_std_string (std::string &s, + ACE_CDR::ULong b) + : val_ (s), + bound_ (b) +{ +} + +ACE_INLINE +ACE_OutputCDR::from_std_string::from_std_string (const std::string &ws, + ACE_CDR::ULong b) + : val_ (ws), + bound_ (b) +{ +} + +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_INLINE +ACE_InputCDR::to_std_wstring::to_std_wstring (std::wstring &s, + ACE_CDR::ULong b) + : val_ (s), + bound_ (b) +{ +} + +ACE_INLINE +ACE_OutputCDR::from_std_wstring::from_std_wstring (const std::wstring &ws, + ACE_CDR::ULong b) + : val_ (ws), + bound_ (b) +{ +} +#endif + ACE_INLINE ACE_InputCDR::Transfer_Contents::Transfer_Contents (ACE_InputCDR &rhs) : rhs_ (rhs) @@ -301,6 +335,26 @@ ACE_OutputCDR::write_wstring (const ACE_CDR::WChar *x) return this->write_wstring (0, 0); } +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_string (const std::string &x) +{ + ACE_CDR::ULong const len = + static_cast (x.size ()); + return this->write_string (len, + x.empty () ? 0 : x.c_str ()); +} + +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_INLINE ACE_CDR::Boolean +ACE_OutputCDR::write_wstring (const std::wstring &x) +{ + ACE_CDR::ULong const len = + static_cast (x.size ()); + return this->write_wstring (len, + x.empty () ? 0 : x.c_str ()); +} +#endif + ACE_INLINE ACE_CDR::Boolean ACE_OutputCDR::write_char_array (const ACE_CDR::Char *x, ACE_CDR::ULong length) @@ -1220,6 +1274,46 @@ operator<< (ACE_OutputCDR &os, const ACE_CDR::WChar *x) return (ACE_CDR::Boolean) os.good_bit (); } +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_OutputCDR::from_std_string x) +{ + ACE_CDR::ULong len = + static_cast (x.val_.size ()); + + os.write_string (len, x.val_.c_str ()); + return + (ACE_CDR::Boolean) (os.good_bit () && (!x.bound_ || len <= x.bound_)); +} + +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, ACE_OutputCDR::from_std_wstring x) +{ + ACE_CDR::ULong len = + static_cast (x.val_.size ()); + + os.write_wstring (len, x.val_.c_str ()); + return + (ACE_CDR::Boolean) (os.good_bit () && (!x.bound_ || len <= x.bound_)); +} +#endif + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, const std::string& x) +{ + os.write_string (x); + return (ACE_CDR::Boolean) os.good_bit (); +} + +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_OutputCDR &os, const std::wstring& x) +{ + os.write_wstring (x); + return (ACE_CDR::Boolean) os.good_bit (); +} +#endif + // The following use the helper classes ACE_INLINE ACE_CDR::Boolean operator<< (ACE_OutputCDR &os, ACE_OutputCDR::from_boolean x) @@ -1359,6 +1453,20 @@ operator>> (ACE_InputCDR &is, ACE_CDR::WChar *&x) return is.read_wstring (x) && is.good_bit (); } +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, std::string& x) +{ + return is.read_string (x) && is.good_bit (); +} + +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, std::wstring& x) +{ + return is.read_wstring (x) && is.good_bit (); +} +#endif + // The following use the helper classes ACE_INLINE ACE_CDR::Boolean operator>> (ACE_InputCDR &is, ACE_InputCDR::to_boolean x) @@ -1406,6 +1514,29 @@ operator>> (ACE_InputCDR &is, ACE_InputCDR::to_wstring x) || ACE_OS::strlen (x.val_) <= x.bound_)); } +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_InputCDR::to_std_string x) +{ + // check if the bounds are satisfied + return + (is.read_string (x.val_) + && is.good_bit () + && (!x.bound_ + || static_cast (x.val_.size ()) <= x.bound_)); +} + +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_INLINE ACE_CDR::Boolean +operator>> (ACE_InputCDR &is, ACE_InputCDR::to_std_wstring x) +{ + // check if the bounds are satisfied + return + (is.read_wstring (x.val_) + && is.good_bit () + && (!x.bound_ + || static_cast (x.val_.size ()) <= x.bound_)); +} +#endif // *************************************************************************** // We must define these methods here because they use the "read_*" inlined // methods of the ACE_InputCDR class diff --git a/ACE/ace/Codeset_IBM1047.cpp b/ACE/ace/Codeset_IBM1047.cpp index ba8d1eb9cd7..edfd2bab4df 100644 --- a/ACE/ace/Codeset_IBM1047.cpp +++ b/ACE/ace/Codeset_IBM1047.cpp @@ -119,6 +119,42 @@ ACE_IBM1047_ISO8859::read_string (ACE_InputCDR& in, return 0; } +ACE_CDR::Boolean +ACE_IBM1047_ISO8859::read_string (ACE_InputCDR& in, + std::string & x) +{ +#if defined (ACE_HAS_CPP11) + ACE_CDR::ULong len; + + in.read_ulong (len); + + if (len > 0) + { + try + { + x.resize (len); + } + catch (const std::bad_alloc&) + { + return false; + } + + if (this->read_char_array (in, &x[0], len)) + { + x.resize (len-1); // drop terminating '\0' read from stream + return true; + } + + delete [] x; + } + + x.clear (); + return false; +#else + return this->ACE_Char_Codeset_Translator::read_string (in, x); +#endif +} + ACE_CDR::Boolean ACE_IBM1047_ISO8859::read_char_array (ACE_InputCDR& in, ACE_CDR::Char* x, @@ -236,6 +272,42 @@ ACE_ISO8859_IBM1047::read_string (ACE_InputCDR &in, return 0; } +ACE_CDR::Boolean +ACE_ISO8859_IBM1047::read_string (ACE_InputCDR& in, + std::string & x) +{ +#if defined (ACE_HAS_CPP11) + ACE_CDR::ULong len; + + in.read_ulong (len); + + if (len > 0) + { + try + { + x.resize (len); + } + catch (const std::bad_alloc&) + { + return false; + } + + if (this->read_char_array (in, &x[0], len)) + { + x.resize (len-1); // drop terminating '\0' read from stream + return true; + } + + delete [] x; + } + + x.clear (); + return false; +#else + return this->ACE_Char_Codeset_Translator::read_string (in, x); +#endif +} + ACE_CDR::Boolean ACE_ISO8859_IBM1047::read_char_array (ACE_InputCDR &in, ACE_CDR::Char *x, diff --git a/ACE/ace/Codeset_IBM1047.h b/ACE/ace/Codeset_IBM1047.h index d04b5997b34..d9d84aa4019 100644 --- a/ACE/ace/Codeset_IBM1047.h +++ b/ACE/ace/Codeset_IBM1047.h @@ -53,6 +53,8 @@ public: ACE_CDR::Char &); virtual ACE_CDR::Boolean read_string (ACE_InputCDR &, ACE_CDR::Char *&); + virtual ACE_CDR::Boolean read_string (ACE_InputCDR &, + std::string &); virtual ACE_CDR::Boolean read_char_array (ACE_InputCDR &, ACE_CDR::Char *, ACE_CDR::ULong); @@ -96,6 +98,8 @@ public: ACE_CDR::Char &); virtual ACE_CDR::Boolean read_string (ACE_InputCDR &, ACE_CDR::Char *&); + virtual ACE_CDR::Boolean read_string (ACE_InputCDR &, + std::string &); virtual ACE_CDR::Boolean read_char_array (ACE_InputCDR &, ACE_CDR::Char *, ACE_CDR::ULong); diff --git a/ACE/tests/CDR_Test.cpp b/ACE/tests/CDR_Test.cpp index cdb099b4c75..f07a7ea9928 100644 --- a/ACE/tests/CDR_Test.cpp +++ b/ACE/tests/CDR_Test.cpp @@ -35,6 +35,10 @@ struct CDR_Test_Types ACE_CDR::Long l; const ACE_CDR::Char *str; const ACE_CDR::WChar *wstr; + const std::string std_str; +#if !defined(ACE_LACKS_STD_WSTRING) + const std::wstring std_wstr; +#endif ACE_CDR::Double d; ACE_CDR::Short reps; ACE_CDR::UShort repus; @@ -67,6 +71,10 @@ CDR_Test_Types::CDR_Test_Types (void) l (4), str ("abc"), wstr (0), + std_str ("xyz"), +#if !defined(ACE_LACKS_STD_WSTRING) + std_wstr (L"xyz"), +#endif d (8), reps (-123), repus (456), @@ -103,6 +111,10 @@ short_stream (void) ACE_CDR::WChar wchar2[] = {'\x00'}; // empty wide string ACE_CDR::WChar *wstr = wchar2; ACE_CString str ("Test String"); + std::string std_str ("std string"); +#if !defined(ACE_LACKS_STD_WSTRING) + std::wstring std_wstr (L"std wstring"); +#endif ACE_CDR::Short s = -123; ACE_CDR::UShort us = 123; ACE_CDR::Long l = -65800L; @@ -124,6 +136,10 @@ short_stream (void) os << fwc; os << str; os << wstr; + os << std_str; +#if !defined(ACE_LACKS_STD_WSTRING) + os << std_wstr; +#endif os << s; os << us; os << l; @@ -142,6 +158,10 @@ short_stream (void) ss << fwc; ss << str; ss << wstr; + ss << std_str; +#if !defined(ACE_LACKS_STD_WSTRING) + ss << std_wstr; +#endif ss << s; ss << us; ss << l; @@ -195,6 +215,10 @@ short_stream (void) ACE_CDR::WChar wch1 = '\x00'; ACE_CDR::WChar *wstr1 = 0; ACE_CString str1; + std::string std_str1; +#if !defined(ACE_LACKS_STD_WSTRING) + std::wstring std_wstr1; +#endif ACE_CDR::Short s1 = 0; ACE_CDR::UShort us1 = 0; ACE_CDR::Long l1 = 0L; @@ -222,6 +246,10 @@ short_stream (void) // @todo Lose the ACE_Auto_Array_Ptr. We should be using a // std::string, or the like. ACE_Auto_Array_Ptr safe_wstr (wstr1); + is >> std_str1; +#if !defined(ACE_LACKS_STD_WSTRING) + is >> std_wstr1; +#endif is >> s1; is >> us1; is >> l1; @@ -258,6 +286,19 @@ short_stream (void) ACE_TEXT ("wide string transfer error")), 1); + if (std_str1 != std_str) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("std::string transfer error")), + 1); + +#if !defined(ACE_LACKS_STD_WSTRING) + if (std_wstr1 != std_wstr) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("std::wstring transfer error")), + 1); +#endif if (s1 != s) ACE_ERROR_RETURN ((LM_ERROR, @@ -375,6 +416,19 @@ CDR_Test_Types::test_put (ACE_OutputCDR &cdr) i), 1); + if (cdr.write_string (this->std_str) == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("write_string(std)[%d] failed\n"), + i), + 1); + +#if !defined(ACE_LACKS_STD_WSTRING) + if (cdr.write_wstring (this->std_wstr) == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("write_wstring(std)[%d] failed\n"), + i), + 1); +#endif } return 0; @@ -465,6 +519,32 @@ CDR_Test_Types::test_get (ACE_InputCDR &cdr) const ACE_TEXT ("wstring[%d] differs\n"), i), 1); + + std::string std_xstr; + if (cdr.read_string (std_xstr) == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("read_string(std)[%d] failed\n"), + i), + 1); + if (std_xstr != this->std_str) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("std::string[%d] differs\n"), + i), + 1); + +#if !defined(ACE_LACKS_STD_WSTRING) + std::wstring std_xwstr; + if (cdr.read_wstring (std_xwstr) == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("read_wstring(std)[%d] failed\n"), + i), + 1); + if (std_xwstr != this->std_wstr) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("std::wstring[%d] differs\n"), + i), + 1); +#endif } return 0; } diff --git a/TAO/tao/CDR.h b/TAO/tao/CDR.h index 65d120186f0..3360714ffe4 100644 --- a/TAO/tao/CDR.h +++ b/TAO/tao/CDR.h @@ -442,25 +442,6 @@ public: /// Called after demarshalling. void reset_vt_indirect_maps (); - /// Helper classes for extracting bounded strings into std::string/wstring. - struct TAO_Export to_std_string - { - to_std_string (std::string &s, - ACE_CDR::ULong b); - std::string &val_; - ACE_CDR::ULong bound_; - }; - -#if !defined(ACE_LACKS_STD_WSTRING) - struct TAO_Export to_std_wstring - { - to_std_wstring (std::wstring &ws, - ACE_CDR::ULong b); - std::wstring &val_; - ACE_CDR::ULong bound_; - }; -#endif /* ACE_LACKS_STD_WSTRING */ - private: /// The ORB_Core, required to extract object references. TAO_ORB_Core* orb_core_; @@ -509,9 +490,13 @@ TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os, ACE_OutputCDR::from_wstring x); TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os, const std::string &x); +TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os, + ACE_OutputCDR::from_std_string x); #if !defined(ACE_LACKS_STD_WSTRING) TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os, const std::wstring &x); +TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os, + ACE_OutputCDR::from_std_wstring x); #endif /* ACE_LACKS_STD_WSTRING */ // CDR input operators for CORBA types @@ -545,12 +530,12 @@ TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os, TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os, std::string &x); TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os, - TAO_InputCDR::to_std_string x); + ACE_InputCDR::to_std_string x); #if !defined(ACE_LACKS_STD_WSTRING) TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os, std::wstring &x); TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os, - TAO_InputCDR::to_std_wstring x); + ACE_InputCDR::to_std_wstring x); #endif /* ACE_LACKS_STD_WSTRING */ TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CDR.inl b/TAO/tao/CDR.inl index fcf3d9d5b13..c4fb156fcc5 100644 --- a/TAO/tao/CDR.inl +++ b/TAO/tao/CDR.inl @@ -326,24 +326,6 @@ TAO_InputCDR::reset_vt_indirect_maps () } } -ACE_INLINE -TAO_InputCDR::to_std_string::to_std_string (std::string &s, - ACE_CDR::ULong b) - : val_ (s), - bound_ (b) -{ -} - -#if !defined(ACE_LACKS_STD_WSTRING) -ACE_INLINE -TAO_InputCDR::to_std_wstring::to_std_wstring (std::wstring &s, - ACE_CDR::ULong b) - : val_ (s), - bound_ (b) -{ -} -#endif /* ACE_LACKS_STD_WSTRING */ - // **************************************************************** ACE_INLINE CORBA::Boolean operator<< (TAO_OutputCDR &os, @@ -472,14 +454,52 @@ ACE_INLINE CORBA::Boolean operator<< (TAO_OutputCDR &os, ACE_INLINE CORBA::Boolean operator<< (TAO_OutputCDR &os, const std::string &x) { +#if defined (ACE_HAS_CPP11) + return + os.fragment_stream (ACE_CDR::OCTET_ALIGN, + sizeof (char)) + && static_cast (os) << x; +#else return os << x.c_str (); +#endif +} + +ACE_INLINE CORBA::Boolean operator<< (TAO_OutputCDR &os, + ACE_OutputCDR::from_std_string x) +{ + if (x.bound_ != 0 && + static_cast (x.val_.size ()) > x.bound_) + { + throw CORBA::BAD_PARAM (); + } + return os << x.val_; } #if !defined(ACE_LACKS_STD_WSTRING) ACE_INLINE CORBA::Boolean operator<< (TAO_OutputCDR &os, const std::wstring &x) { +#if defined (ACE_HAS_CPP11) + return + os.fragment_stream ((sizeof (CORBA::WChar) == 2 + ? ACE_CDR::SHORT_ALIGN + : ACE_CDR::LONG_ALIGN), + sizeof (CORBA::WChar)) + && static_cast (os) << x; +#else return os << x.c_str (); +#endif +} + +ACE_INLINE CORBA::Boolean operator<< (TAO_OutputCDR &os, + ACE_OutputCDR::from_std_wstring x) +{ + if (x.bound_ != 0 && + static_cast (x.val_.size ()) > x.bound_) + { + throw CORBA::BAD_PARAM (); + } + return os << x.val_; } #endif /* ACE_LACKS_STD_WSTRING */ @@ -580,15 +600,11 @@ ACE_INLINE CORBA::Boolean operator>> (TAO_InputCDR &is, ACE_INLINE CORBA::Boolean operator>> (TAO_InputCDR &is, std::string &x) { - char *buf = 0; - CORBA::Boolean const marshal_flag = is >> buf; - x.assign (buf); - ACE::strdelete (buf); - return marshal_flag; + return static_cast (is) >> x; } ACE_INLINE CORBA::Boolean operator>> (TAO_InputCDR &is, - TAO_InputCDR::to_std_string x) + ACE_InputCDR::to_std_string x) { CORBA::Boolean const marshal_flag = is >> x.val_; if (marshal_flag && x.bound_ != 0 && x.val_.size () > x.bound_) @@ -602,15 +618,11 @@ ACE_INLINE CORBA::Boolean operator>> (TAO_InputCDR &is, ACE_INLINE CORBA::Boolean operator>> (TAO_InputCDR &is, std::wstring &x) { - CORBA::WChar *buf = 0; - CORBA::Boolean const marshal_flag = is >> buf; - x.assign (buf); - ACE::strdelete (buf); - return marshal_flag; + return static_cast (is) >> x; } ACE_INLINE CORBA::Boolean operator>> (TAO_InputCDR &is, - TAO_InputCDR::to_std_wstring x) + ACE_InputCDR::to_std_wstring x) { CORBA::Boolean const marshal_flag = is >> x.val_; if (marshal_flag && x.bound_ != 0 && x.val_.size () > x.bound_) diff --git a/TAO/tao/Codeset/UTF16_BOM_Translator.cpp b/TAO/tao/Codeset/UTF16_BOM_Translator.cpp index ad66904c07a..0d0169cdd11 100644 --- a/TAO/tao/Codeset/UTF16_BOM_Translator.cpp +++ b/TAO/tao/Codeset/UTF16_BOM_Translator.cpp @@ -165,6 +165,74 @@ TAO_UTF16_BOM_Translator::read_wstring (ACE_InputCDR &cdr, return 0; } +#if !defined(ACE_LACKS_STD_WSTRING) +ACE_CDR::Boolean +TAO_UTF16_BOM_Translator::read_wstring (ACE_InputCDR &cdr, + std::wstring &x) +{ +#if defined (ACE_HAS_CPP11) + ACE_CDR::ULong len; + if (!this->read_4 (cdr, &len)) + return false; + + // A check for the length being too great is done later in the + // call to read_char_array but we want to have it done before + // the memory is allocated. + if (len > 0 && len <= cdr.length ()) + { + if (static_cast (this->major_version (cdr)) == 1 + && static_cast (this->minor_version (cdr)) > 1) + { + len /= ACE_UTF16_CODEPOINT_SIZE; + + try + { + x.resize (len); + } + catch (const std::bad_alloc&) + { + return false; + } + + if (this->read_wchar_array_i (cdr, &x[0], len, 1)) + { + // Since reading the array may have adjusted the length, + // shrink to fit + x.resize (len); + return true; + } + } + else + { + try + { + x.resize (len); + } + catch (const std::bad_alloc&) + { + return false; + } + + if (this->read_wchar_array (cdr, &x[0], len)) + { + x.resize (len-1); // drop terminating zero wchar read from stream + return true; + } + } + } + else if (len == 0) + { + x.clear (); + return true; + } + x.clear (); + return false; +#else + return this->ACE_WChar_Codeset_Translator::read_wstring (cdr, x); +#endif +} +#endif + ACE_CDR::Boolean TAO_UTF16_BOM_Translator::read_wchar_array_i (ACE_InputCDR & cdr, ACE_CDR::WChar *x, diff --git a/TAO/tao/Codeset/UTF16_BOM_Translator.h b/TAO/tao/Codeset/UTF16_BOM_Translator.h index 20d9ac2ad1e..19c3b8eb159 100644 --- a/TAO/tao/Codeset/UTF16_BOM_Translator.h +++ b/TAO/tao/Codeset/UTF16_BOM_Translator.h @@ -52,6 +52,10 @@ public: ACE_CDR::WChar &); virtual ACE_CDR::Boolean read_wstring (ACE_InputCDR &, ACE_CDR::WChar *&); +#if !defined(ACE_LACKS_STD_WSTRING) + virtual ACE_CDR::Boolean read_wstring (ACE_InputCDR&, + std::wstring &); +#endif virtual ACE_CDR::Boolean read_wchar_array (ACE_InputCDR &, ACE_CDR::WChar *, ACE_CDR::ULong); diff --git a/TAO/tao/Codeset/UTF8_Latin1_Translator.cpp b/TAO/tao/Codeset/UTF8_Latin1_Translator.cpp index 5dfb557ff0b..6da6df8f67a 100644 --- a/TAO/tao/Codeset/UTF8_Latin1_Translator.cpp +++ b/TAO/tao/Codeset/UTF8_Latin1_Translator.cpp @@ -117,6 +117,55 @@ TAO_UTF8_Latin1_Translator::read_string (ACE_InputCDR &cdr, return 0; } +ACE_CDR::Boolean +TAO_UTF8_Latin1_Translator::read_string (ACE_InputCDR &cdr, + std::string &x) +{ +#if defined (ACE_HAS_CPP11) + ACE_CDR::ULong len; + if (!cdr.read_ulong (len)) + return false; + + // A check for the length being too great is done later in the + // call to read_char_array but we want to have it done before + // the memory is allocated. + if (len > 0 && len <= cdr.length()) + { + // detract terminating '\0' from length + len--; + try + { + x.resize (len); + } + catch (const std::bad_alloc&) + { + return false; + } + + // pos keeps track of the character position, it will never be + // greater than len + size_t pos = 0; + ACE_CDR::ULong incr = 1; + for (ACE_CDR::ULong i = 0; incr > 0 && i < len; i += incr) + { + incr = this->read_char_i(cdr,x[pos++]); + } + if (incr > 0) + { + // read terminating '\0' from stream + ACE_CDR::Char c; + incr = this->read_char_i(cdr, c); + return (incr > 0); + } + } + + x.clear (); + return false; +#else + return this->ACE_Char_Codeset_Translator::read_string (cdr, x); +#endif +} + ACE_CDR::Boolean TAO_UTF8_Latin1_Translator::read_char_array (ACE_InputCDR & cdr, ACE_CDR::Char *x, diff --git a/TAO/tao/Codeset/UTF8_Latin1_Translator.h b/TAO/tao/Codeset/UTF8_Latin1_Translator.h index 2fac7ed1f80..6bccd0bee8c 100644 --- a/TAO/tao/Codeset/UTF8_Latin1_Translator.h +++ b/TAO/tao/Codeset/UTF8_Latin1_Translator.h @@ -56,6 +56,8 @@ public: ACE_CDR::Char &); virtual ACE_CDR::Boolean read_string (ACE_InputCDR &, ACE_CDR::Char *&); + virtual ACE_CDR::Boolean read_string (ACE_InputCDR &, + std::string &); virtual ACE_CDR::Boolean read_char_array (ACE_InputCDR &, ACE_CDR::Char *, ACE_CDR::ULong); -- cgit v1.2.1