summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormcorino <mcorino@remedy.nl>2018-08-05 17:45:31 +0200
committerGitHub <noreply@github.com>2018-08-05 17:45:31 +0200
commitc7571f5ff80763484bf073f37dabfed0cb7983cc (patch)
tree376554590363f60baf51396dcaac22007d31883d
parentf475da3f3220f507ce3d9b21793819a1aee65a48 (diff)
parent4a09b0b10cbea1fdcb16161583ee22f7d151784b (diff)
downloadATCD-c7571f5ff80763484bf073f37dabfed0cb7983cc.tar.gz
Merge pull request #656 from mcorino/mco-feature-4310-string-cdr-optimize
add full support for streaming std::(w)string
-rw-r--r--ACE/ace/CDR_Size.h10
-rw-r--r--ACE/ace/CDR_Size.inl36
-rw-r--r--ACE/ace/CDR_Stream.cpp164
-rw-r--r--ACE/ace/CDR_Stream.h79
-rw-r--r--ACE/ace/CDR_Stream.inl131
-rw-r--r--ACE/ace/Codeset_IBM1047.cpp72
-rw-r--r--ACE/ace/Codeset_IBM1047.h4
-rw-r--r--ACE/tests/CDR_Test.cpp80
-rw-r--r--TAO/tao/CDR.h27
-rw-r--r--TAO/tao/CDR.inl72
-rw-r--r--TAO/tao/Codeset/UTF16_BOM_Translator.cpp68
-rw-r--r--TAO/tao/Codeset/UTF16_BOM_Translator.h4
-rw-r--r--TAO/tao/Codeset/UTF8_Latin1_Translator.cpp49
-rw-r--r--TAO/tao/Codeset/UTF8_Latin1_Translator.h2
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 <x> 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
@@ -144,6 +144,26 @@ ACE_SizeCDR::write_wstring (const ACE_CDR::WChar *x)
}
ACE_INLINE ACE_CDR::Boolean
+ACE_SizeCDR::write_string (const std::string &x)
+{
+ ACE_CDR::ULong len =
+ static_cast<ACE_CDR::ULong> (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<ACE_CDR::ULong> (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<ACE_CDR::Short> (this->major_version_) == 1
+ && static_cast<ACE_CDR::Short> (this->minor_version_) == 2)
+ {
+ len /=
+ ACE_Utils::truncate_cast<ACE_CDR::ULong> (
+ 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
@@ -128,6 +128,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)
{
@@ -302,6 +336,26 @@ ACE_OutputCDR::write_wstring (const ACE_CDR::WChar *x)
}
ACE_INLINE ACE_CDR::Boolean
+ACE_OutputCDR::write_string (const std::string &x)
+{
+ ACE_CDR::ULong const len =
+ static_cast<ACE_CDR::ULong> (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<ACE_CDR::ULong> (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<ACE_CDR::ULong> (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<ACE_CDR::ULong> (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<ACE_CDR::ULong> (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<ACE_CDR::ULong> (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
@@ -120,6 +120,42 @@ ACE_IBM1047_ISO8859::read_string (ACE_InputCDR& in,
}
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,
ACE_CDR::ULong len)
@@ -237,6 +273,42 @@ ACE_ISO8859_IBM1047::read_string (ACE_InputCDR &in,
}
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,
ACE_CDR::ULong len)
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<ACE_CDR::WChar> 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<ACE_OutputCDR &> (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<ACE_CDR::ULong> (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<ACE_OutputCDR &> (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<ACE_CDR::ULong> (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<ACE_InputCDR &> (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<ACE_InputCDR &> (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<ACE_CDR::Short> (this->major_version (cdr)) == 1
+ && static_cast<ACE_CDR::Short> (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
@@ -118,6 +118,55 @@ TAO_UTF8_Latin1_Translator::read_string (ACE_InputCDR &cdr,
}
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,
ACE_CDR::ULong length)
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);