From b055d8b2f7da61e5db0f20043ea6a8180d02719d Mon Sep 17 00:00:00 2001 From: boris Date: Sun, 10 Apr 2005 11:15:04 +0000 Subject: ChangeLogTag: Sun Apr 10 13:25:26 2005 Boris Kolpackov --- ace/CDR_Size.cpp | 244 +++++++++++++++++++++++ ace/CDR_Size.h | 233 ++++++++++++++++++++++ ace/CDR_Size.inl | 417 ++++++++++++++++++++++++++++++++++++++++ ace/Makefile.am | 3 + ace/ace.mpc | 1 + protocols/ace/RMCast/Link.cpp | 2 - protocols/ace/RMCast/Protocol.h | 256 ++++++++++++++++-------- tests/CDR_Test.cpp | 27 ++- 8 files changed, 1103 insertions(+), 80 deletions(-) create mode 100644 ace/CDR_Size.cpp create mode 100644 ace/CDR_Size.h create mode 100644 ace/CDR_Size.inl diff --git a/ace/CDR_Size.cpp b/ace/CDR_Size.cpp new file mode 100644 index 00000000000..5b0e6797f5e --- /dev/null +++ b/ace/CDR_Size.cpp @@ -0,0 +1,244 @@ +#include "ace/CDR_Size.h" + +#if !defined (__ACE_INLINE__) +# include "ace/CDR_Size.inl" +#endif /* ! __ACE_INLINE__ */ + +#include "ace/SString.h" + +ACE_RCSID (ace, + CDR_Size, + "$Id$") + +ACE_CDR::Boolean +ACE_SizeCDR::write_wchar (ACE_CDR::WChar x) +{ + // Note: translator framework is not supported. + // + if (ACE_OutputCDR::wchar_maxbytes () == 0) + { + errno = EACCES; + return (this->good_bit_ = false); + } + if (static_cast (major_version_) == 1 + && static_cast (minor_version_) == 2) + { + ACE_CDR::Octet len = + static_cast (ACE_OutputCDR::wchar_maxbytes ()); + if (this->write_1 (&len)) + { + if (ACE_OutputCDR::wchar_maxbytes () == sizeof(ACE_CDR::WChar)) + return + this->write_octet_array ( + reinterpret_cast (&x), + static_cast (len)); + else + if (ACE_OutputCDR::wchar_maxbytes () == 2) + { + ACE_CDR::Short sx = static_cast (x); + return + this->write_octet_array ( + reinterpret_cast (&sx), + static_cast (len)); + } + else + { + ACE_CDR::Octet ox = static_cast (x); + return + this->write_octet_array ( + reinterpret_cast (&ox), + static_cast (len)); + } + } + } + else if (static_cast (minor_version_) == 0) + { // wchar is not allowed with GIOP 1.0. + errno = EINVAL; + return (this->good_bit_ = false); + } + if (ACE_OutputCDR::wchar_maxbytes () == sizeof (ACE_CDR::WChar)) + return this->write_4 (reinterpret_cast (&x)); + else if (ACE_OutputCDR::wchar_maxbytes () == 2) + { + ACE_CDR::Short sx = static_cast (x); + return this->write_2 (reinterpret_cast (&sx)); + } + ACE_CDR::Octet ox = static_cast (x); + return this->write_1 (reinterpret_cast (&ox)); +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_string (ACE_CDR::ULong len, + const ACE_CDR::Char *x) +{ + // Note: translator framework is not supported. + // + if (len != 0) + { + if (this->write_ulong (len + 1)) + return this->write_char_array (x, len + 1); + } + else + { + // Be nice to programmers: treat nulls as empty strings not + // errors. (OMG-IDL supports languages that don't use the C/C++ + // notion of null v. empty strings; nulls aren't part of the OMG-IDL + // string model.) + if (this->write_ulong (1)) + return this->write_char (0); + } + + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_string (const ACE_CString &x) +{ + // @@ Leave this method in here, not the `.i' file so that we don't + // have to unnecessarily pull in the `ace/SString.h' header. + return this->write_string (static_cast (x.length ()), + x.c_str()); +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_wstring (ACE_CDR::ULong len, + const ACE_CDR::WChar *x) +{ + // Note: translator framework is not supported. + // + if (ACE_OutputCDR::wchar_maxbytes () == 0) + { + errno = EACCES; + return (this->good_bit_ = false); + } + + if (static_cast (this->major_version_) == 1 + && static_cast (this->minor_version_) == 2) + { + if (x != 0) + { + //In GIOP 1.2 the length field contains the number of bytes + //the wstring occupies rather than number of wchars + //Taking sizeof might not be a good way! This is a temporary fix. + if (this->write_ulong (ACE_OutputCDR::wchar_maxbytes () * len)) + return this->write_wchar_array (x, len); + } + else + //In GIOP 1.2 zero length wstrings are legal + return this->write_ulong (0); + } + + else + if (x != 0) + { + if (this->write_ulong (len + 1)) + return this->write_wchar_array (x, len + 1); + } + else if (this->write_ulong (1)) + return this->write_wchar (0); + return (this->good_bit_ = false); +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_1 (const ACE_CDR::Octet *x) +{ + ACE_UNUSED_ARG (x); + this->adjust (1); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_2 (const ACE_CDR::UShort *x) +{ + ACE_UNUSED_ARG (x); + this->adjust (ACE_CDR::SHORT_SIZE); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_4 (const ACE_CDR::ULong *x) +{ + ACE_UNUSED_ARG (x); + this->adjust (ACE_CDR::LONG_SIZE); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_8 (const ACE_CDR::ULongLong *x) +{ + ACE_UNUSED_ARG (x); + this->adjust (ACE_CDR::LONGLONG_SIZE); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_16 (const ACE_CDR::LongDouble *x) +{ + ACE_UNUSED_ARG (x); + this->adjust (ACE_CDR::LONGDOUBLE_SIZE, + ACE_CDR::LONGDOUBLE_ALIGN); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_wchar_array_i (const ACE_CDR::WChar *x, + ACE_CDR::ULong length) +{ + ACE_UNUSED_ARG (x); + + if (length == 0) + return true; + + const size_t align = (ACE_OutputCDR::wchar_maxbytes () == 2) ? + ACE_CDR::SHORT_ALIGN : + ACE_CDR::OCTET_ALIGN; + + this->adjust (ACE_OutputCDR::wchar_maxbytes () * length, align); + return true; +} + + +ACE_CDR::Boolean +ACE_SizeCDR::write_array (const void *x, + size_t size, + size_t align, + ACE_CDR::ULong length) +{ + ACE_UNUSED_ARG (x); + + if (length == 0) + return true; + + this->adjust (size * length, align); + return true; +} + +ACE_CDR::Boolean +ACE_SizeCDR::write_boolean_array (const ACE_CDR::Boolean* x, + ACE_CDR::ULong length) +{ + ACE_UNUSED_ARG (x); + this->adjust (length, 1); + return true; +} + +void +ACE_SizeCDR::adjust (size_t size) +{ + return adjust (size, size); +} + +void +ACE_SizeCDR::adjust (size_t size, + size_t align) +{ + size_ = align * (size_ / align + (size_ % align ? 1 : 0)); + size_ += size; +} + +ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, const ACE_CString &x) +{ + ss.write_string (x); + return ss.good_bit (); +} diff --git a/ace/CDR_Size.h b/ace/CDR_Size.h new file mode 100644 index 00000000000..b52b04486c7 --- /dev/null +++ b/ace/CDR_Size.h @@ -0,0 +1,233 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CDR_Size.h + * + * $Id$ + * + * + * ACE Common Data Representation (CDR) size-calculating stream. + * + * + * The current implementation assumes that the host has 1-byte, + * 2-byte and 4-byte integral types, and that it has single + * precision and double precision IEEE floats. + * Those assumptions are pretty good these days, with Crays beign + * the only known exception. + * + * + * @author Boris Kolpackov + * + */ +//============================================================================= + +#ifndef ACE_CDR_SIZE_H +#define ACE_CDR_SIZE_H + +#include /**/ "ace/pre.h" + +#include "ace/CDR_Base.h" +#include "ace/CDR_Stream.h" // for ACE_OutputCDR::from_* + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SStringfwd.h" + +/** + * @class ACE_SizeCDR + * + * @brief A CDR stream for calculating size of the representation. + * + */ +class ACE_Export ACE_SizeCDR +{ +public: + /// Default constructor. + ACE_SizeCDR (ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION, + ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION); + + /// Returns @c false if an error has ocurred. + bool good_bit (void) const; + + + /// Reset current size. + void reset (void); + + + /// Return current size. + size_t total_length (void) const; + + + // Return 0 on failure and 1 on success. + //@{ @name Size-calculating pseudo-write operations + ACE_CDR::Boolean write_boolean (ACE_CDR::Boolean x); + ACE_CDR::Boolean write_char (ACE_CDR::Char x); + ACE_CDR::Boolean write_wchar (ACE_CDR::WChar x); + ACE_CDR::Boolean write_octet (ACE_CDR::Octet x); + ACE_CDR::Boolean write_short (ACE_CDR::Short x); + ACE_CDR::Boolean write_ushort (ACE_CDR::UShort x); + ACE_CDR::Boolean write_long (ACE_CDR::Long x); + ACE_CDR::Boolean write_ulong (ACE_CDR::ULong x); + ACE_CDR::Boolean write_longlong (const ACE_CDR::LongLong &x); + ACE_CDR::Boolean write_ulonglong (const ACE_CDR::ULongLong &x); + ACE_CDR::Boolean write_float (ACE_CDR::Float x); + ACE_CDR::Boolean write_double (const ACE_CDR::Double &x); + ACE_CDR::Boolean write_longdouble (const ACE_CDR::LongDouble &x); + + /// For string we offer methods that accept a precomputed length. + ACE_CDR::Boolean write_string (const ACE_CDR::Char *x); + ACE_CDR::Boolean write_string (ACE_CDR::ULong len, + const ACE_CDR::Char *x); + ACE_CDR::Boolean write_string (const ACE_CString &x); + ACE_CDR::Boolean write_wstring (const ACE_CDR::WChar *x); + ACE_CDR::Boolean write_wstring (ACE_CDR::ULong length, + const ACE_CDR::WChar *x); + //@} + + /// Note: the portion written starts at and ends + /// at . + /// The length is *NOT* stored into the CDR stream. + //@{ @name Array write operations + ACE_CDR::Boolean write_boolean_array (const ACE_CDR::Boolean *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_char_array (const ACE_CDR::Char *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_wchar_array (const ACE_CDR::WChar* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_octet_array (const ACE_CDR::Octet* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_short_array (const ACE_CDR::Short *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_ushort_array (const ACE_CDR::UShort *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_long_array (const ACE_CDR::Long *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_ulong_array (const ACE_CDR::ULong *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_longlong_array (const ACE_CDR::LongLong* x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_ulonglong_array (const ACE_CDR::ULongLong *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_float_array (const ACE_CDR::Float *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_double_array (const ACE_CDR::Double *x, + ACE_CDR::ULong length); + ACE_CDR::Boolean write_longdouble_array (const ACE_CDR::LongDouble* x, + ACE_CDR::ULong length); + + /// + /// Adjust to and count octets. + void adjust (size_t size); + + /// As above, but now the size and alignment requirements may be + /// different. + void adjust (size_t size, + size_t align); + +private: + /// disallow copying... + ACE_SizeCDR (const ACE_SizeCDR& rhs); + ACE_SizeCDR& operator= (const ACE_SizeCDR& rhs); + + ACE_CDR::Boolean write_1 (const ACE_CDR::Octet *x); + ACE_CDR::Boolean write_2 (const ACE_CDR::UShort *x); + ACE_CDR::Boolean write_4 (const ACE_CDR::ULong *x); + ACE_CDR::Boolean write_8 (const ACE_CDR::ULongLong *x); + ACE_CDR::Boolean write_16 (const ACE_CDR::LongDouble *x); + + /** + * write an array of elements, each of bytes and the + * start aligned at a multiple of . The elements are assumed + * to be packed with the right alignment restrictions. It is mostly + * designed for buffers of the basic types. + * + * This operation uses ; as explained above it is expected + * that using assignment is faster that for one element, + * but for several elements should be more efficient, it + * could be interesting to find the break even point and optimize + * for that case, but that would be too platform dependent. + */ + ACE_CDR::Boolean write_array (const void *x, + size_t size, + size_t align, + ACE_CDR::ULong length); + + + ACE_CDR::Boolean write_wchar_array_i (const ACE_CDR::WChar* x, + ACE_CDR::ULong length); + +private: + /// Set to false when an error ocurrs. + bool good_bit_; + + /// Current size. + size_t size_; + +protected: + /// GIOP version information + ACE_CDR::Octet major_version_; + ACE_CDR::Octet minor_version_; +}; + + +// @@ This operator should not be inlined since they force SString.h +// to be included in this header. +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + const ACE_CString &x); + +#if defined (__ACE_INLINE__) +# include "ace/CDR_Size.inl" +#else /* __ACE_INLINE__ */ + +// Not used by CORBA or TAO +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Char x); + +// CDR size-calculating output operators for primitive types + +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Short x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::UShort x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Long x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::ULong x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::LongLong x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::ULongLong x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR& ss, + ACE_CDR::LongDouble x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Float x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_CDR::Double x); + +// CDR size-calculating output operator from helper classes + +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_boolean x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_char x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_wchar x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_octet x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_string x); +extern ACE_Export ACE_CDR::Boolean operator<< (ACE_SizeCDR &ss, + ACE_OutputCDR::from_wstring x); +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); + +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* ACE_CDR_SIZE_H */ diff --git a/ace/CDR_Size.inl b/ace/CDR_Size.inl new file mode 100644 index 00000000000..7697b9abdf7 --- /dev/null +++ b/ace/CDR_Size.inl @@ -0,0 +1,417 @@ +// -*- C++ -*- +// +// $Id$ + +#include "ace/OS_NS_string.h" + + +ACE_INLINE +ACE_SizeCDR::ACE_SizeCDR (ACE_CDR::Octet major_version, + ACE_CDR::Octet minor_version) + : good_bit_ (true), + size_ (0), + major_version_ (major_version), + minor_version_ (minor_version) +{ +} + +ACE_INLINE bool +ACE_SizeCDR::good_bit (void) const +{ + return this->good_bit_; +} + +ACE_INLINE void +ACE_SizeCDR::reset (void) +{ + this->size_ = 0; +} + +ACE_INLINE size_t +ACE_SizeCDR::total_length (void) const +{ + return this->size_; +} + + +// Encode the CDR stream. + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_octet (ACE_CDR::Octet x) +{ + return this->write_1 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_boolean (ACE_CDR::Boolean x) +{ + return (ACE_CDR::Boolean) this->write_octet (x ? (ACE_CDR::Octet) 1 : (ACE_CDR::Octet) 0); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_char (ACE_CDR::Char x) +{ + // Note: translator framework is not supported. + // + return this->write_1 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_short (ACE_CDR::Short x) +{ + return this->write_2 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ushort (ACE_CDR::UShort x) +{ + return this->write_2 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_long (ACE_CDR::Long x) +{ + return this->write_4 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ulong (ACE_CDR::ULong x) +{ + return this->write_4 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_longlong (const ACE_CDR::LongLong &x) +{ + return this->write_8 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ulonglong (const ACE_CDR::ULongLong &x) +{ + return this->write_8 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_float (ACE_CDR::Float x) +{ + return this->write_4 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_double (const ACE_CDR::Double &x) +{ + return this->write_8 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_longdouble (const ACE_CDR::LongDouble &x) +{ + return this->write_16 (reinterpret_cast (&x)); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_string (const ACE_CDR::Char *x) +{ + if (x != 0) + { + const ACE_CDR::ULong len = + static_cast (ACE_OS::strlen (x)); + return this->write_string (len, x); + } + return this->write_string (0, 0); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_wstring (const ACE_CDR::WChar *x) +{ + if (x != 0) + { + ACE_CDR::ULong len = + static_cast (ACE_OS::strlen (x)); + return this->write_wstring (len, x); + } + return this->write_wstring (0, 0); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_char_array (const ACE_CDR::Char *x, + ACE_CDR::ULong length) +{ + // Note: translator framework is not supported. + // + return this->write_array (x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_wchar_array (const ACE_CDR::WChar* x, + ACE_CDR::ULong length) +{ + // Note: translator framework is not supported. + // + if (ACE_OutputCDR::wchar_maxbytes () == 0) + { + errno = EACCES; + return (ACE_CDR::Boolean) (this->good_bit_ = false); + } + if (ACE_OutputCDR::wchar_maxbytes () == sizeof (ACE_CDR::WChar)) + return this->write_array (x, + sizeof (ACE_CDR::WChar), + sizeof (ACE_CDR::WChar) == 2 + ? ACE_CDR::SHORT_ALIGN + : ACE_CDR::LONG_ALIGN, + length); + return this->write_wchar_array_i (x,length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_octet_array (const ACE_CDR::Octet* x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::OCTET_SIZE, + ACE_CDR::OCTET_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_short_array (const ACE_CDR::Short *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::SHORT_SIZE, + ACE_CDR::SHORT_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ushort_array (const ACE_CDR::UShort *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::SHORT_SIZE, + ACE_CDR::SHORT_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_long_array (const ACE_CDR::Long *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ulong_array (const ACE_CDR::ULong *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_longlong_array (const ACE_CDR::LongLong *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_ulonglong_array (const ACE_CDR::ULongLong *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_float_array (const ACE_CDR::Float *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONG_SIZE, + ACE_CDR::LONG_ALIGN, + length); +} + + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_double_array (const ACE_CDR::Double *x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGLONG_SIZE, + ACE_CDR::LONGLONG_ALIGN, + length); +} + +ACE_INLINE ACE_CDR::Boolean +ACE_SizeCDR::write_longdouble_array (const ACE_CDR::LongDouble* x, + ACE_CDR::ULong length) +{ + return this->write_array (x, + ACE_CDR::LONGDOUBLE_SIZE, + ACE_CDR::LONGDOUBLE_ALIGN, + length); +} + + +// **************************************************************** + + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Char x) +{ + ss.write_char (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Short x) +{ + ss.write_short (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::UShort x) +{ + ss.write_ushort (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Long x) +{ + ss.write_long (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::ULong x) +{ + ss.write_ulong (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::LongLong x) +{ + ss.write_longlong (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::ULongLong x) +{ + ss.write_ulonglong (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::LongDouble x) +{ + ss.write_longdouble (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Float x) +{ + ss.write_float (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_CDR::Double x) +{ + ss.write_double (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, const ACE_CDR::Char *x) +{ + ss.write_string (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, const ACE_CDR::WChar *x) +{ + ss.write_wstring (x); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +// The following use the helper classes +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_boolean x) +{ + ss.write_boolean (x.val_); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_char x) +{ + ss.write_char (x.val_); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_wchar x) +{ + ss.write_wchar (x.val_); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_octet x) +{ + ss.write_octet (x.val_); + return (ACE_CDR::Boolean) ss.good_bit (); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_string x) +{ + ACE_CDR::ULong len = 0; + + if (x.val_ != 0) + { + len = static_cast (ACE_OS::strlen (x.val_)); + } + + ss.write_string (len, x.val_); + return + (ACE_CDR::Boolean) (ss.good_bit () && (!x.bound_ || len <= x.bound_)); +} + +ACE_INLINE ACE_CDR::Boolean +operator<< (ACE_SizeCDR &ss, ACE_OutputCDR::from_wstring x) +{ + ACE_CDR::ULong len = 0; + + if (x.val_ != 0) + { + len = static_cast (ACE_OS::strlen (x.val_)); + } + + ss.write_wstring (len, x.val_); + return + (ACE_CDR::Boolean) (ss.good_bit () && (!x.bound_ || len <= x.bound_)); +} + diff --git a/ace/Makefile.am b/ace/Makefile.am index 9b014c36649..0f187217025 100644 --- a/ace/Makefile.am +++ b/ace/Makefile.am @@ -54,6 +54,7 @@ libACE_la_SOURCES = \ Basic_Types.cpp \ CDR_Base.cpp \ CDR_Stream.cpp \ + CDR_Size.cpp \ Capabilities.cpp \ Cleanup.cpp \ Codecs.cpp \ @@ -398,6 +399,8 @@ nobase_include_HEADERS = \ CDR_Base.inl \ CDR_Stream.h \ CDR_Stream.inl \ + CDR_Size.h \ + CDR_Size.inl \ CORBA_macros.h \ Cache_Map_Manager_T.cpp \ Cache_Map_Manager_T.h \ diff --git a/ace/ace.mpc b/ace/ace.mpc index 5827ca7ce00..c7d80ded027 100644 --- a/ace/ace.mpc +++ b/ace/ace.mpc @@ -45,6 +45,7 @@ project(ACE) : acedefaults, core, other, codecs, token, svcconf, uuid, filecache Capabilities.cpp CDR_Base.cpp CDR_Stream.cpp + CDR_Size.cpp Cleanup.cpp Codeset_IBM1047.cpp Codeset_Registry.cpp diff --git a/protocols/ace/RMCast/Link.cpp b/protocols/ace/RMCast/Link.cpp index 0bc9e482d6e..afde178cc90 100644 --- a/protocols/ace/RMCast/Link.cpp +++ b/protocols/ace/RMCast/Link.cpp @@ -175,8 +175,6 @@ namespace ACE_RMCast Address addr; - //@@ CDR-specific. - // // Block for up to timeout time waiting for an incomming message. // for (;;) diff --git a/protocols/ace/RMCast/Protocol.h b/protocols/ace/RMCast/Protocol.h index ca5e54102c8..6fc6f1be912 100644 --- a/protocols/ace/RMCast/Protocol.h +++ b/protocols/ace/RMCast/Protocol.h @@ -11,6 +11,8 @@ #include "ace/Hash_Map_Manager.h" #include "ace/CDR_Stream.h" +#include "ace/CDR_Size.h" + #include "ace/INET_Addr.h" #include "ace/Null_Mutex.h" @@ -47,6 +49,7 @@ namespace ACE_RMCast // typedef ACE_OutputCDR ostream; + typedef ACE_SizeCDR sstream; typedef ACE_InputCDR istream; struct Profile; @@ -105,13 +108,13 @@ namespace ACE_RMCast } protected: - Profile (u16 id, u16 size, u16 boundary) - : header_ (id, size), boundary_ (boundary) + Profile (u16 id) + : header_ (id, 0) { } - Profile (Header const& h, u16 boundary) - : header_ (h), boundary_ (boundary) + Profile (Header const& h) + : header_ (h) { } public: @@ -127,12 +130,6 @@ namespace ACE_RMCast return header_.size (); } - u16 - boundary () const - { - return boundary_; - } - protected: void size (u16 s) @@ -140,17 +137,33 @@ namespace ACE_RMCast header_.size (s); } + u16 + calculate_size () + { + sstream ss; + + serialize_body (ss); + + return static_cast (ss.total_length ()); + } + public: virtual void serialize_body (ostream&) const = 0; + virtual void + serialize_body (sstream&) const = 0; + friend ostream& operator<< (ostream& os, Profile const& p); + friend + sstream& + operator<< (sstream& ss, Profile const& p); + private: Header header_; - u16 boundary_; }; inline @@ -163,6 +176,16 @@ namespace ACE_RMCast return os; } + inline + sstream& + operator<< (sstream& ss, Profile::Header const& hdr) + { + ss << hdr.id (); + ss << hdr.size (); + + return ss; + } + inline ostream& operator<< (ostream& os, Profile const& p) @@ -173,6 +196,16 @@ namespace ACE_RMCast return os; } + inline + sstream& + operator<< (sstream& ss, Profile const& p) + { + ss << p.header_; + p.serialize_body (ss); + + return ss; + } + // // // @@ -232,20 +265,18 @@ namespace ACE_RMCast size_t size () const { - size_t s (4); // 4 is for size (u32) + sstream ss; + + u32 s; + + ss << s; for (Profiles::const_iterator i (profiles_); !i.done (); i.advance ()) { - //@@ This is so broken: in CDR the padding depends on - // what comes after. - // - s += s % 2; // Padding to the boundary of 2. - s += 4; // Profile header: u16 + u16 - s += s % (*i).int_id_->boundary (); // Padding to the b. of profile body. - s += (*i).int_id_->size (); // Profile body. + ss << *((*i).int_id_); } - return s; + return ss.total_length (); } friend @@ -271,14 +302,7 @@ namespace ACE_RMCast Profiles profiles_; }; -#if defined (__BORLANDC__) && (__BORLANDC__ <= 0x570) - // Borland C++ Builder 6 and earlier don't handle default template - // arguments correctly. Provide an explicit template argument. typedef ACE_Vector Messages; -#else - typedef ACE_Vector Messages; -#endif /* __BORLANDC__ <= 0x570 */ - // // @@ -295,7 +319,7 @@ namespace ACE_RMCast public: From (Header const& h, istream& is) - : Profile (h, 4) + : Profile (h) { u32 addr; u16 port; @@ -306,11 +330,10 @@ namespace ACE_RMCast address_ = Address (port, addr); } - // 6 is CDR-specific. - // From (Address const& addr) - : Profile (id, 6, 4), address_ (addr) + : Profile (id), address_ (addr) { + size (calculate_size ()); } public: @@ -331,6 +354,16 @@ namespace ACE_RMCast os << port; } + virtual void + serialize_body (sstream& ss) const + { + u32 addr; + u16 port; + + ss << addr; + ss << port; + } + private: Address address_; }; @@ -351,7 +384,7 @@ namespace ACE_RMCast public: To (Header const& h, istream& is) - : Profile (h, 4) + : Profile (h) { u32 addr; u16 port; @@ -362,11 +395,10 @@ namespace ACE_RMCast address_ = Address (port, addr); } - // 6 is CDR-specific. - // To (Address const& addr) - : Profile (id, 6, 4), address_ (addr) + : Profile (id), address_ (addr) { + size (calculate_size ()); } public: @@ -387,6 +419,16 @@ namespace ACE_RMCast os << port; } + virtual void + serialize_body (sstream& ss) const + { + u32 addr; + u16 port; + + ss << addr; + ss << port; + } + private: Address address_; }; @@ -406,24 +448,25 @@ namespace ACE_RMCast public: Data (Header const& h, istream& is) - : Profile (h, 1), buf_ (0), size_ (h.size ()) + : Profile (h), buf_ (0), size_ (h.size ()) { if (size_) { buf_ = reinterpret_cast (operator new (size_)); is.read_char_array (buf_, size_); } - } Data (void const* buf, size_t s) - : Profile (id, s, 1), buf_ (0), size_ (s) + : Profile (id), buf_ (0), size_ (s) { if (size_) { buf_ = reinterpret_cast (operator new (size_)); ACE_OS::memcpy (buf_, buf, size_); } + + Profile::size (calculate_size ()); } public: @@ -446,6 +489,12 @@ namespace ACE_RMCast os.write_char_array (buf_, size_); } + virtual void + serialize_body (sstream& ss) const + { + ss.write_char_array (buf_, size_); + } + private: char* buf_; size_t size_; @@ -466,16 +515,15 @@ namespace ACE_RMCast public: SN (Header const& h, istream& is) - : Profile (h, 8) + : Profile (h) { is >> n_; } - // 8 is CDR-specific. - // SN (u64 n) - : Profile (id, 8, 8), n_ (n) + : Profile (id), n_ (n) { + size (calculate_size ()); } public: @@ -492,6 +540,12 @@ namespace ACE_RMCast os << n_; } + virtual void + serialize_body (sstream& ss) const + { + ss << n_; + } + private: u64 n_; }; @@ -512,44 +566,47 @@ namespace ACE_RMCast static u16 const id; -#if defined (__BORLANDC__) && (__BORLANDC__ <= 0x570) - // Borland C++ Builder 6 and earlier don't handle default template - // arguments correctly. Provide an explicit template argument. typedef ACE_Vector SerialNumbers; -#else - typedef ACE_Vector SerialNumbers; -#endif /* __BORLANDC__ <= 0x570 */ - typedef SerialNumbers::Iterator iterator; NAK (Header const& h, istream& is) - : Profile (h, 8) + : Profile (h) { - //@@ All the numbers are CDR-specific. - // - // 8 = u32 + u16 + 2(padding to u64) + u64 sn; + u32 addr; + u16 port; + + sstream ss; + + ss << sn; + size_t sn_size (ss.total_length ()); + + ss.reset (); + + ss << addr; + ss << port; + + size_t addr_size (ss.total_length ()); + + // num_of_sns = (size - addr_size) / sn_size // - for (long i (0); i < ((h.size () - 8) / 8); ++i) + for (unsigned long i (0); i < ((h.size () - addr_size) / sn_size); ++i) { - u64 sn; is >> sn; sns_.push_back (sn); } - u32 addr; - u16 port; - - is >> port; is >> addr; + is >> port; + address_ = Address (port, addr); } - // 8 is CDR-specific. - // NAK (Address const& src) - : Profile (id, 8, 8), address_ (src) + : Profile (id), address_ (src) { + size (calculate_size ()); } public: @@ -557,7 +614,7 @@ namespace ACE_RMCast add (u64 sn) { sns_.push_back (sn); - size (size () + 8); //@@ 8 is CDR-specific + size (calculate_size ()); } public: @@ -607,8 +664,29 @@ namespace ACE_RMCast u32 addr (address_.get_ip_address ()); u16 port (address_.get_port_number ()); - os << port; os << addr; + os << port; + } + + virtual void + serialize_body (sstream& ss) const + { + NAK& this_ = const_cast (*this); // Don't put in ROM. + + // Stone age iteration. + // + for (iterator i (this_.begin ()); !i.done (); i.advance ()) + { + u64 sn; + ss << sn; + } + + + u32 addr; + u16 port; + + ss << addr; + ss << port; } private: @@ -631,28 +709,38 @@ namespace ACE_RMCast public: NRTM (Header const& h, istream& is) - : Profile (h, 8), map_ (10) + : Profile (h), map_ (10) { - //@@ 16 is CDR-specific. + u32 addr; + u16 port; + u64 sn; + + sstream ss; + + ss << sn; + ss << addr; + ss << port; + + size_t block_size (ss.total_length ()); + + + // num_of_blocks = size / block_size // - // 16 = u32 + u16 + 2(padding to u64) + u64 - for (u16 i (0); i < (h.size () / 16); ++i) + for (u16 i (0); i < (h.size () / block_size); ++i) { - u32 addr; - u16 port; - u64 sn; - is >> sn; - is >> port; is >> addr; + is >> port; + map_.bind (Address (port, addr), sn); } } NRTM () - : Profile (id, 0, 8), map_ (10) + : Profile (id), map_ (10) { + size (calculate_size ()); } public: @@ -661,7 +749,7 @@ namespace ACE_RMCast { map_.bind (addr, sn); - size (size () + 16); //@@ 16 is CDR-specific. + size (calculate_size ()); } u64 @@ -691,8 +779,23 @@ namespace ACE_RMCast u64 sn ((*i).int_id_); os << sn; - os << port; os << addr; + os << port; + } + } + + virtual void + serialize_body (sstream& ss) const + { + for (Map::const_iterator i (map_), e (map_, 1); i != e; ++i) + { + u32 addr; + u16 port; + u64 sn; + + ss << sn; + ss << addr; + ss << port; } } @@ -721,5 +824,4 @@ operator<< (std::ostream& os, RMCast::Address const& a) } */ - #endif // ACE_RMCAST_PROTOCOL_H diff --git a/tests/CDR_Test.cpp b/tests/CDR_Test.cpp index bc07ac45499..d8bba133b92 100644 --- a/tests/CDR_Test.cpp +++ b/tests/CDR_Test.cpp @@ -22,6 +22,7 @@ #include "ace/Get_Opt.h" #include "ace/Auto_Ptr.h" #include "ace/CDR_Stream.h" +#include "ace/CDR_Size.h" #include "ace/SString.h" #include "ace/ACE.h" #include "ace/OS_NS_stdlib.h" @@ -77,6 +78,7 @@ short_stream (void) // Build an output stream ACE_OutputCDR os; + ACE_SizeCDR ss; // Basic types for output ACE_CDR::Char ch = 'A'; @@ -99,8 +101,8 @@ short_stream (void) ACE_CDR::Double d_array[3] = { -123.456789, 0.0, 123.456789 }; ACE_OutputCDR::from_char fc (ch); - os << fc; ACE_OutputCDR::from_wchar fwc (wch); + os << fc; os << fwc; os << str; os << wstr; @@ -115,6 +117,29 @@ short_stream (void) os.write_float_array (f_array, 3); os.write_double_array (d_array, 3); + // Do the same for size stream. + ss << fc; + ss << fwc; + ss << str; + ss << wstr; + ss << s; + ss << us; + ss << l; + ss << ul; + ss << f; + ss << d; + ss.write_short_array (s_array, 3); + ss.write_long_array (l_array, 3); + ss.write_float_array (f_array, 3); + ss.write_double_array (d_array, 3); + + // Check the size. + if (ss.total_length () != os.total_length ()) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("representation length does not match")), + 1); + const ACE_Message_Block *out_mb = os.begin (); size_t len = out_mb->length (); -- cgit v1.2.1