diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-08-14 20:12:03 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-08-14 20:12:03 +0000 |
commit | da49b08671e5d87c9996bb0bcc63c661447f83b2 (patch) | |
tree | 4b92710abc7aef7d79efb811391b9254038b5480 /TAO/tao | |
parent | 66e74009620c1297b07ce26dab97f586ed76edc7 (diff) | |
download | ATCD-da49b08671e5d87c9996bb0bcc63c661447f83b2.tar.gz |
ChangeLogTag:Fri Aug 14 14:44:49 1998 Carlos O'Ryan <coryan@cs.wustl.edu>
Diffstat (limited to 'TAO/tao')
-rw-r--r-- | TAO/tao/IIOP_Interpreter.cpp | 2 | ||||
-rw-r--r-- | TAO/tao/Object.cpp | 16 | ||||
-rw-r--r-- | TAO/tao/Object.h | 40 | ||||
-rw-r--r-- | TAO/tao/Object.i | 8 | ||||
-rw-r--r-- | TAO/tao/Sequence.cpp | 15 | ||||
-rw-r--r-- | TAO/tao/Sequence.h | 17 | ||||
-rw-r--r-- | TAO/tao/Sequence_T.cpp | 347 | ||||
-rw-r--r-- | TAO/tao/Sequence_T.h | 128 | ||||
-rw-r--r-- | TAO/tao/Sequence_T.i | 55 | ||||
-rw-r--r-- | TAO/tao/corba.h | 1 | ||||
-rw-r--r-- | TAO/tao/decode.cpp | 40 | ||||
-rw-r--r-- | TAO/tao/deep_free.cpp | 9 | ||||
-rw-r--r-- | TAO/tao/encode.cpp | 38 | ||||
-rw-r--r-- | TAO/tao/orbconf.h | 4 | ||||
-rw-r--r-- | TAO/tao/varout.cpp | 55 | ||||
-rw-r--r-- | TAO/tao/varout.h | 96 | ||||
-rw-r--r-- | TAO/tao/varout.i | 100 |
17 files changed, 916 insertions, 55 deletions
diff --git a/TAO/tao/IIOP_Interpreter.cpp b/TAO/tao/IIOP_Interpreter.cpp index 674519ec16b..ff93db56664 100644 --- a/TAO/tao/IIOP_Interpreter.cpp +++ b/TAO/tao/IIOP_Interpreter.cpp @@ -168,7 +168,7 @@ declare_entry (CORBA::Any, tk_any); declare_entry (CORBA::TypeCode_ptr, tk_TypeCode); declare_entry (CORBA::Principal_ptr, tk_Principal); -declare_entry (CORBA::Object_ptr, tk_objref); +declare_entry (TAO_Object_Field_T<CORBA_Object>, tk_objref); declare_entry (CORBA::String, tk_string); #if !defined (TAO_NO_COPY_OCTET_SEQUENCES) diff --git a/TAO/tao/Object.cpp b/TAO/tao/Object.cpp index 7f3fc766d9e..8f6904e327d 100644 --- a/TAO/tao/Object.cpp +++ b/TAO/tao/Object.cpp @@ -257,3 +257,19 @@ CORBA::Object::_use_locate_requests (CORBA::Boolean use_it) iiopobj->use_locate_requests (use_it); } + +// **************************************************************** + +TAO_Object_Field::~TAO_Object_Field (void) +{ +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class TAO_Object_Field_T<CORBA_Object>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate TAO_Object_Field_T<CORBA_Object> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/tao/Object.h b/TAO/tao/Object.h index 58ae31182f0..0850f510974 100644 --- a/TAO/tao/Object.h +++ b/TAO/tao/Object.h @@ -28,15 +28,22 @@ class TAO_ServantBase; class STUB_Object; +class CORBA_Object; +typedef CORBA_Object* CORBA_Object_ptr; + class TAO_Export CORBA_Object { public: - static CORBA::Object_ptr _duplicate (CORBA::Object_ptr obj); + static CORBA_Object_ptr _duplicate (CORBA_Object_ptr obj); // increment the ref count - static CORBA::Object_ptr _nil (void); + static CORBA_Object_ptr _nil (void); // return a NUL object + static CORBA_Object_ptr _narrow (CORBA_Object_ptr obj, + CORBA::Environment& env); + // no-op it is just here to simplify some templates. + // These calls correspond to over-the-wire operations, or at least // do so in many common cases. The normal implementation assumes a // particular simple, efficient, protocol-neutral interface for @@ -197,6 +204,35 @@ private: CORBA::Object_ptr &ptr_; }; +class TAO_Object_Field +{ + // = TITLE + // Base class to represent fields (in structures) corresponding to + // object references. + // + // = DESCRIPTION + // When an object reference appears in a structure the marshaling + // and demarhsaling of the structure gets complicated: + // the interpreter can only marshal CORBA_Object_ptr when it + // dermarshal it creates on of those objects. + // The downcasting to the right type must be executed by classes + // with compile-time knowledge of the object type. + // The solution addopted in TAO is to create a special manager + // class for that field called TAO_Object_Field_T<T> (see + // varout.h), this class serves as an abstract interface to + // manipulate instances of those classes (by the interpreter, of + // course). + // +public: + virtual ~TAO_Object_Field (void); + // destructor + + virtual void _downcast (CORBA_Object* base_ptr, + CORBA_Environment& env) = 0; + virtual CORBA_Object* _upcast (void) = 0; + virtual void _release (void) = 0; +}; + #if defined (__ACE_INLINE__) # include "tao/Object.i" #endif /* __ACE_INLINE__ */ diff --git a/TAO/tao/Object.i b/TAO/tao/Object.i index 98ece395a43..aa84c3361c2 100644 --- a/TAO/tao/Object.i +++ b/TAO/tao/Object.i @@ -24,7 +24,7 @@ CORBA_Object::_decr_refcnt (void) } ACE_INLINE CORBA_Object_ptr -CORBA_Object::_duplicate (CORBA::Object_ptr obj) +CORBA_Object::_duplicate (CORBA_Object_ptr obj) { if (obj) obj->_incr_refcnt (); @@ -39,6 +39,12 @@ CORBA_Object::_nil (void) return 0; } +ACE_INLINE CORBA_Object_ptr +CORBA_Object::_narrow (CORBA_Object_ptr obj, CORBA::Environment&) +{ + return obj; +} + ACE_INLINE CORBA::Boolean CORBA::is_nil (CORBA::Object_ptr obj) { diff --git a/TAO/tao/Sequence.cpp b/TAO/tao/Sequence.cpp index 7538f768bd7..aa5faa52340 100644 --- a/TAO/tao/Sequence.cpp +++ b/TAO/tao/Sequence.cpp @@ -21,6 +21,21 @@ void TAO_Base_Sequence::_shrink_buffer (CORBA::ULong, CORBA::ULong) // default is no op. } +void +TAO_Base_Sequence::_downcast (void*, + CORBA_Object*, + CORBA_Environment &) +{ + // default is no op. + // @@ TODO Maybe throw an exception? +} + +CORBA_Object* +TAO_Base_Sequence::_upcast (void*) const +{ + return 0; +} + // ************************************************************* // Operations for class TAO_Unbounded_Base_Sequence // ************************************************************* diff --git a/TAO/tao/Sequence.h b/TAO/tao/Sequence.h index 816845bc653..a765cdd4660 100644 --- a/TAO/tao/Sequence.h +++ b/TAO/tao/Sequence.h @@ -18,6 +18,9 @@ #if !defined (TAO_SEQUENCE_H) # define TAO_SEQUENCE_H +class CORBA_Object; +class CORBA_Environment; + class TAO_Export TAO_Base_Sequence { // = TITLE @@ -55,6 +58,16 @@ public: // release the objects only from position <0> to <length-1>; so // shrink and then delete could result in a memory leak. + virtual void _downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env); + // Used for sequences of objects to downcast a recently demarshalled + // object reference into the right type. + + virtual CORBA_Object* _upcast (void* src) const; + // Used for sequences of object to convert from the derived type + // into the Object class. + protected: TAO_Base_Sequence (void); // Default constructor. @@ -461,6 +474,10 @@ private: // **************************************************************** + + +// **************************************************************** + #if defined (__ACE_INLINE__) #include "tao/Sequence.i" #endif /* __ACE_INLINE__ */ diff --git a/TAO/tao/Sequence_T.cpp b/TAO/tao/Sequence_T.cpp index af795395a12..34ca0ad9d28 100644 --- a/TAO/tao/Sequence_T.cpp +++ b/TAO/tao/Sequence_T.cpp @@ -125,19 +125,8 @@ operator= (const TAO_Bounded_Sequence<T, MAX> &rhs) if (this->release_) { -#if 0 // We never need to reallocate the buffer because they are // always of size MAX. - if (this->maximum_ < rhs.maximum_) - { - // free the old buffer - T *tmp = ACE_reinterpret_cast (T *, - this->buffer_); - TAO_Bounded_Sequence<T>::freebuf (tmp); - this->buffer_ = - TAO_Bounded_Sequence<T>::allocbuf (rhs.maximum_); - } -#endif /* 0 */ } else this->buffer_ = @@ -372,7 +361,7 @@ template<class T> void TAO_Unbounded_Object_Sequence<T>::_shrink_buffer (CORBA::ULong nl, CORBA::ULong ol) { - T **tmp = ACE_reinterpret_cast (T**, this->buffer_); + T **tmp = ACE_static_cast (T**, this->buffer_); for (CORBA::ULong i = nl; i < ol; ++i) { @@ -381,6 +370,24 @@ TAO_Unbounded_Object_Sequence<T>::_shrink_buffer (CORBA::ULong nl, } } +template <class T> void +TAO_Unbounded_Object_Sequence<T>::_downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env) +{ + T **tmp = ACE_static_cast (T**, target); + + *tmp = T::_narrow (src, env); +} + +template <class T> CORBA_Object* +TAO_Unbounded_Object_Sequence<T>::_upcast (void* src) const +{ + T **tmp = ACE_static_cast (T**, src); + + return *tmp; +} + // ************************************************************* // Operations for class TAO_Bounded_Object_Sequence // ************************************************************* @@ -425,14 +432,6 @@ TAO_Bounded_Object_Sequence<T, MAX>::operator= } // No need to reallocate the buffer since it is always of size // MAX -#if 0 - if (this->maximum_ < rhs.maximum_) - { - TAO_Bounded_Object_Sequence<T, MAX>::freebuf (tmp); - this->buffer_ = - TAO_Bounded_Object_Sequence<T, MAX>::allocbuf (rhs.maximum_); - } -#endif /* 0 */ } else this->buffer_ = @@ -508,6 +507,304 @@ TAO_Bounded_Object_Sequence<T, MAX>::_shrink_buffer (CORBA::ULong nl, } } +template <class T, CORBA::ULong MAX> void +TAO_Bounded_Object_Sequence<T, MAX>::_downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env) +{ + T **tmp = ACE_static_cast (T**, target); + + *tmp = T::_narrow (src, env); +} + +template <class T, CORBA::ULong MAX> CORBA_Object* +TAO_Bounded_Object_Sequence<T, MAX>::_upcast (void* src) const +{ + T **tmp = ACE_static_cast (T**, src); + + return *tmp; +} + +// ************************************************************* +// Operations for class TAO_Unbounded_Pseudo_Sequence +// ************************************************************* + +// constructor for unbounded seq +template <class T> +TAO_Unbounded_Pseudo_Sequence<T>:: +TAO_Unbounded_Pseudo_Sequence (CORBA::ULong maximum) + : TAO_Unbounded_Base_Sequence (maximum, + TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (maximum)) +{ +} + +template <class T> +TAO_Unbounded_Pseudo_Sequence<T>:: +TAO_Unbounded_Pseudo_Sequence (const TAO_Unbounded_Pseudo_Sequence<T> &rhs) + : TAO_Unbounded_Base_Sequence (rhs) +{ + T **tmp1 = TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (this->maximum_); + T ** const tmp2 = ACE_reinterpret_cast (T ** ACE_CAST_CONST, rhs.buffer_); + + for (CORBA::ULong i = 0; i < rhs.length_; ++i) + tmp1[i] = T::_duplicate (tmp2[i]); + + this->buffer_ = tmp1; +} + +template<class T> +TAO_Unbounded_Pseudo_Sequence<T>::~TAO_Unbounded_Pseudo_Sequence (void) +{ + this->_deallocate_buffer (); +} + +// assignment operator +template <class T> +TAO_Unbounded_Pseudo_Sequence<T>& +TAO_Unbounded_Pseudo_Sequence<T>:: +operator= (const TAO_Unbounded_Pseudo_Sequence<T> &rhs) +{ + if (this == &rhs) + return *this; + + if (this->release_) + { + T **tmp = ACE_reinterpret_cast (T **, + this->buffer_); + + for (CORBA::ULong i = 0; i < this->length_; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } + if (this->maximum_ < rhs.maximum_) + { + TAO_Unbounded_Pseudo_Sequence<T>::freebuf (tmp); + this->buffer_ = + TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (rhs.maximum_); + } + } + else + this->buffer_ = + TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (rhs.maximum_); + + TAO_Unbounded_Base_Sequence::operator= (rhs); + + T **tmp1 = ACE_reinterpret_cast (T **, this->buffer_); + T ** const tmp2 = ACE_reinterpret_cast (T ** ACE_CAST_CONST, rhs.buffer_); + + for (CORBA::ULong i = 0; i < rhs.length_; ++i) + tmp1[i] = T::_duplicate (tmp2[i]); + + return *this; +} + +template <class T> T ** +TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (CORBA::ULong nelems) +{ + T **buf; + + ACE_NEW_RETURN (buf, T*[nelems], 0); + + for (CORBA::ULong i = 0; i < nelems; i++) + buf[i] = T::_nil (); + + return buf; +} + +template <class T> void +TAO_Unbounded_Pseudo_Sequence<T>::freebuf (T **buffer) +{ + if (buffer == 0) + return; + + // {orbos/97-05-15:16.11} The freebuf function ensures that the + // destructor for each element is called before the buffer is + // destroyed, except for string elements, which are freed using + // string_free(), and object reference elements, which are freed + // using release(). The freebuf function will ignore null pointers + // passed to it. + + // @@ How are we supposed to implement that! We don't know the + // length of the buffer here. + // Mark the length in the first four bytes? For the moment we let + // that be. + + delete[] buffer; +} + +template<class T> +void TAO_Unbounded_Pseudo_Sequence<T>::_allocate_buffer (CORBA::ULong length) +{ + T **tmp = TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (length); + + if (this->buffer_ != 0) + { + T **old = ACE_reinterpret_cast (T**, this->buffer_); + for (CORBA::ULong i = 0; i < this->length_; ++i) + // Only call duplicate when we did not own the previous + // buffer, since after this method we own it we must also own + // the objects. If we already own the objects there is no + // need to copy them, if we did we would also have to remove + // the old instances. + if (!this->release_) + tmp[i] = T::_duplicate (old[i]); + else + tmp[i] = old[i]; + + if (this->release_) + delete[] old; + } + this->buffer_ = tmp; +} + +template<class T> +void TAO_Unbounded_Pseudo_Sequence<T>::_deallocate_buffer (void) +{ + if (this->buffer_ == 0 || this->release_ == 0) + return; + T **tmp = ACE_reinterpret_cast (T**, this->buffer_); + for (CORBA::ULong i = 0; i < this->length_; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } + TAO_Unbounded_Pseudo_Sequence<T>::freebuf (tmp); + this->buffer_ = 0; +} + +template<class T> void +TAO_Unbounded_Pseudo_Sequence<T>::_shrink_buffer (CORBA::ULong nl, + CORBA::ULong ol) +{ + T **tmp = ACE_static_cast (T**, this->buffer_); + + for (CORBA::ULong i = nl; i < ol; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } +} + +// ************************************************************* +// Operations for class TAO_Bounded_Pseudo_Sequence +// ************************************************************* + +template <class T, CORBA::ULong MAX> +TAO_Bounded_Pseudo_Sequence<T, MAX>:: +TAO_Bounded_Pseudo_Sequence (void) + : TAO_Bounded_Base_Sequence (MAX, + TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (MAX)) +{ +} + +template <class T, CORBA::ULong MAX> +TAO_Bounded_Pseudo_Sequence<T, MAX>:: +TAO_Bounded_Pseudo_Sequence (const TAO_Bounded_Pseudo_Sequence<T, MAX> &rhs) + : TAO_Bounded_Base_Sequence (rhs) +{ + T **tmp1 = + TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (MAX); + T ** const tmp2 = ACE_reinterpret_cast (T** ACE_CAST_CONST, rhs.buffer_); + for (CORBA::ULong i = 0; i < rhs.length_; i++) + tmp1[i] = T::_duplicate (tmp2[i]); + this->buffer_ = tmp1; +} + +template <class T, CORBA::ULong MAX> +TAO_Bounded_Pseudo_Sequence<T, MAX>& +TAO_Bounded_Pseudo_Sequence<T, MAX>::operator= +(const TAO_Bounded_Pseudo_Sequence<T, MAX> &rhs) +{ + if (this == &rhs) + return *this; + + if (this->release_) + { + T **tmp = ACE_reinterpret_cast (T **, this->buffer_); + + for (CORBA::ULong i = 0; i < this->length_; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } + // No need to reallocate the buffer since it is always of size + // MAX + } + else + this->buffer_ = + TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (rhs.maximum_); + + TAO_Bounded_Base_Sequence::operator= (rhs); + + T **tmp1 = ACE_reinterpret_cast (T **, this->buffer_); + T ** const tmp2 = ACE_reinterpret_cast (T ** ACE_CAST_CONST, rhs.buffer_); + for (CORBA::ULong i=0; i < rhs.length_; ++i) + tmp1[i] = T::_duplicate (tmp2[i]); + return *this; +} + +template <class T, CORBA::ULong MAX> T ** +TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (CORBA::ULong) +{ + T **buf; + + ACE_NEW_RETURN (buf, T*[MAX], 0); + + for (CORBA::ULong i = 0; i < MAX; i++) + buf[i] = T::_nil (); + + return buf; +} + +template <class T, CORBA::ULong MAX> void +TAO_Bounded_Pseudo_Sequence<T, MAX>::freebuf (T **buffer) +{ + // How much do we deallocate? Easy! allocbuf() always creates MAX + // elements and initialize them to T::_nil(). So we can be + // complaint and call CORBA::release() on each one. + for (CORBA::ULong i = 0; i < MAX; ++i) + if (buffer[i] != T::_nil ()) + { + CORBA::release (buffer[i]); + buffer[i] = T::_nil (); + } + + delete[] buffer; +} + +template<class T, CORBA::ULong MAX> void +TAO_Bounded_Pseudo_Sequence<T, MAX>::_allocate_buffer (CORBA::ULong length) +{ + // For this class memory is never reallocated so the implementation + // is *really* simple. + this->buffer_ = + TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (length); +} + +template<class T, CORBA::ULong MAX> +void TAO_Bounded_Pseudo_Sequence<T, MAX>::_deallocate_buffer (void) +{ + if (this->buffer_ == 0 || this->release_ == 0) + return; + T **tmp = ACE_reinterpret_cast (T **, this->buffer_); + TAO_Bounded_Pseudo_Sequence<T, MAX>::freebuf (tmp); + this->buffer_ = 0; +} + +template<class T, CORBA::ULong MAX> void +TAO_Bounded_Pseudo_Sequence<T, MAX>::_shrink_buffer (CORBA::ULong nl, + CORBA::ULong ol) +{ + T **tmp = ACE_reinterpret_cast (T **, this->buffer_); + + for (CORBA::ULong i = nl; i < ol; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } +} + // ************************************************************* // Operations for class TAO_Bounded_String_Sequence // ************************************************************* @@ -553,14 +850,8 @@ TAO_Bounded_String_Sequence<MAX>::operator= CORBA::string_free (tmp[i]); tmp[i] = 0; } -#if 0 - if (this->maximum_ < rhs.maximum_) - { - TAO_Bounded_String_Sequence<T, MAX>::freebuf (tmp); - this->buffer_ = - TAO_Unbounded_String_Sequence<T, MAX>::allocbuf (rhs.maximum_); - } -#endif /* 0 */ + // No need to reallocate because the buffer is supposed to be of + // <MAX> size. } else this->buffer_ = diff --git a/TAO/tao/Sequence_T.h b/TAO/tao/Sequence_T.h index 9a5601ae42b..d1863ca1e13 100644 --- a/TAO/tao/Sequence_T.h +++ b/TAO/tao/Sequence_T.h @@ -310,10 +310,10 @@ class TAO_Unbounded_Object_Sequence : public TAO_Unbounded_Base_Sequence // pseudo objects, object references and strings. // = SPEC - // 16.8 Mapping for Structured Types - // The mapping for struct, union, and sequence (but not array) is a - // C++ struct or class with a default constructor, a copy - // constructor, an assignment operator, and a destructor. + // 16.8 Mapping for Structured Types + // The mapping for struct, union, and sequence (but not array) is a + // C++ struct or class with a default constructor, a copy + // constructor, an assignment operator, and a destructor. // public: // = Initialization and termination methods. @@ -412,6 +412,10 @@ public: virtual void _deallocate_buffer (void); virtual void _shrink_buffer (CORBA::ULong new_length, CORBA::ULong old_length); + virtual void _downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env); + virtual CORBA_Object* _upcast (void* src) const; }; // ************************************************************* @@ -423,9 +427,8 @@ class TAO_Bounded_Object_Sequence : public TAO_Bounded_Base_Sequence // Parametric sequence for types that require managers. // // = DESCRIPTION - // Some IDL types require that sequences on them have a "manager" - // class, in charge of handling the object lifetime, examples are - // pseudo objects, object references and strings. + // Please see the documentation for the unbounded case. + // public: // = Initialization and termination methods. @@ -465,6 +468,117 @@ public: virtual void _deallocate_buffer (void); virtual void _shrink_buffer (CORBA::ULong new_length, CORBA::ULong old_length); + virtual void _downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env); + virtual CORBA_Object* _upcast (void* src) const; +}; + +// ************************************************************* + +template<class T> +class TAO_Unbounded_Pseudo_Sequence : public TAO_Unbounded_Base_Sequence +{ + // = TITLE + // Parametric sequence for pseudo objects. + // + // = DESCRIPTION + // Some IDL types (including pseudo objects) require that + // sequences on them have a "manager" class, in charge of handling + // the object lifetime. + // This parametric class implements those sequences. In general + // the sequence is similar to Object_Sequente, except for some + // TAO internal details. The complete documentation of each method + // is provided in TAO_Unbounded_Object_Sequece +public: + // = Initialization and termination methods. + + TAO_Unbounded_Pseudo_Sequence (void); + // default ctor + + TAO_Unbounded_Pseudo_Sequence (CORBA::ULong max); + // Constructor with a "hint" for the maximum capacity. + + TAO_Unbounded_Pseudo_Sequence (CORBA::ULong maximum, + CORBA::ULong length, + T* *data, + CORBA::Boolean release=0); + // Constructor with a given buffer. + + TAO_Unbounded_Pseudo_Sequence(const TAO_Unbounded_Pseudo_Sequence<T> &); + // Copy ctor, deep copies. + + ~TAO_Unbounded_Pseudo_Sequence (void); + // dtor releases all the contained elements. + + TAO_Unbounded_Pseudo_Sequence<T> &operator= (const TAO_Unbounded_Pseudo_Sequence <T> &); + // The assignment operator first releases all object reference + // members and frees all string members, and then performs a + // deepcopy to create a new structure. + + TAO_Object_Manager<T> operator[] (CORBA::ULong index) const; + // read-write accessor + + static T **allocbuf (CORBA::ULong); + // The allocbuf function allocates a vector of T elements that can + // be passed to the T *data constructor. + + static void freebuf (T **); + // Release all the elements. + + // The Base_Sequence functions, please see "tao/Sequence.h" + virtual void _allocate_buffer (CORBA::ULong length); + virtual void _deallocate_buffer (void); + virtual void _shrink_buffer (CORBA::ULong new_length, + CORBA::ULong old_length); +}; + +// ************************************************************* + +template<class T, CORBA::ULong MAX> +class TAO_Bounded_Pseudo_Sequence : public TAO_Bounded_Base_Sequence +{ + // = TITLE + // Bounded version of TAO_Unbounded_Psuedo_Sequence. + // + // = DESCRIPTION + // Please see the documentation for the unbounded case. + // +public: + // = Initialization and termination methods. + + TAO_Bounded_Pseudo_Sequence (void); + // default ctor. + + TAO_Bounded_Pseudo_Sequence (CORBA::ULong length, + T* *value, + CORBA::Boolean release=0); + // Constructor from data. + + TAO_Bounded_Pseudo_Sequence (const TAO_Bounded_Pseudo_Sequence<T,MAX> &); + // Copy constructor. + + ~TAO_Bounded_Pseudo_Sequence (void); + // destructor + + TAO_Bounded_Pseudo_Sequence &operator= (const TAO_Bounded_Pseudo_Sequence<T,MAX> &); + // Assignment from another Bounded sequence. + + TAO_Object_Manager<T> operator[] (CORBA::ULong index) const; + // Read-write accessor. + + static T **allocbuf (CORBA::ULong length); + // Allocate storage for a sequence.. + + static void freebuf (T **buffer); + // Free a buffer allocated by allocbuf() and release each element on + // it. + + // The Base_Sequence functions, please see "tao/sequence.h" + virtual void _allocate_buffer (CORBA::ULong length); + virtual void _deallocate_buffer (void); + virtual void _shrink_buffer (CORBA::ULong new_length, + CORBA::ULong old_length); }; // ************************************************************* diff --git a/TAO/tao/Sequence_T.i b/TAO/tao/Sequence_T.i index eaca5865c42..8ab52ad0560 100644 --- a/TAO/tao/Sequence_T.i +++ b/TAO/tao/Sequence_T.i @@ -313,6 +313,61 @@ TAO_Bounded_Object_Sequence<T, MAX>::operator[] (CORBA::ULong index) const } // ************************************************************* +// class TAO_Unbounded_Pseudo_Sequence +// ************************************************************* + +//default constructor +template <class T> ACE_INLINE +TAO_Unbounded_Pseudo_Sequence<T>::TAO_Unbounded_Pseudo_Sequence (void) +{ +} + +template <class T> ACE_INLINE +TAO_Unbounded_Pseudo_Sequence<T>:: +TAO_Unbounded_Pseudo_Sequence (CORBA::ULong maximum, + CORBA::ULong length, + T* *value, + CORBA::Boolean release) + : TAO_Unbounded_Base_Sequence (maximum, length, value, release) +{ +} + +template <class T> ACE_INLINE TAO_Object_Manager<T> +TAO_Unbounded_Pseudo_Sequence<T>::operator[] (CORBA::ULong index) const +{ + ACE_ASSERT (index < this->maximum_); + T ** const tmp = ACE_reinterpret_cast (T ** ACE_CAST_CONST, this->buffer_); + return TAO_Object_Manager<T> (tmp + index, this->release_); +} + +// ************************************************************* +// class TAO_Bounded_Pseudo_Sequence +// ************************************************************* + +template<class T, CORBA::ULong MAX> ACE_INLINE +TAO_Bounded_Pseudo_Sequence<T,MAX>::~TAO_Bounded_Pseudo_Sequence (void) +{ + this->_deallocate_buffer (); +} + +template <class T, CORBA::ULong MAX> ACE_INLINE +TAO_Bounded_Pseudo_Sequence<T,MAX>:: +TAO_Bounded_Pseudo_Sequence (CORBA::ULong length, + T **value, + CORBA::Boolean release) + : TAO_Bounded_Base_Sequence (MAX, length, value, release) +{ +} + +template <class T, CORBA::ULong MAX> ACE_INLINE TAO_Object_Manager<T> +TAO_Bounded_Pseudo_Sequence<T, MAX>::operator[] (CORBA::ULong index) const +{ + ACE_ASSERT (index < this->maximum_); + T **const tmp = ACE_reinterpret_cast (T ** ACE_CAST_CONST, this->buffer_); + return TAO_Object_Manager<T> (tmp + index, this->release_); +} + +// ************************************************************* // class TAO_Bounded_String_Sequence // ************************************************************* diff --git a/TAO/tao/corba.h b/TAO/tao/corba.h index 5ee93974f74..665110dfd2b 100644 --- a/TAO/tao/corba.h +++ b/TAO/tao/corba.h @@ -175,6 +175,7 @@ operator>>(TAO_InputCDR&, TAO_opaque&); #include "tao/Request.h" #include "tao/Stub.h" #include "tao/Object.h" +#include "tao/varout.h" #include "tao/Typecode.h" // Marshaling diff --git a/TAO/tao/decode.cpp b/TAO/tao/decode.cpp index 13c0ffc1731..86664cb6bd9 100644 --- a/TAO/tao/decode.cpp +++ b/TAO/tao/decode.cpp @@ -799,7 +799,6 @@ TAO_Marshal_Struct::decode (CORBA::TypeCode_ptr tc, stream->read_wchar (*(CORBA::WChar *) data); break; case CORBA::tk_TypeCode: - case CORBA::tk_objref: case CORBA::tk_any: case CORBA::tk_Principal: case CORBA::tk_struct: @@ -812,6 +811,17 @@ TAO_Marshal_Struct::decode (CORBA::TypeCode_ptr tc, case CORBA::tk_wstring: retval = stream->decode (param, data, 0, env); break; + + case CORBA::tk_objref: + { + CORBA_Object_ptr object; + retval = stream->decode (param, &object, 0, env); + TAO_Object_Field* field = + ACE_static_cast(TAO_Object_Field*, data); + field->_downcast (object, env); + } + break; + default: break; } @@ -1237,7 +1247,6 @@ TAO_Marshal_Sequence::decode (CORBA::TypeCode_ptr tc, break; // handle all aggregate types here - case CORBA::tk_objref: case CORBA::tk_string: case CORBA::tk_wstring: case CORBA::tk_any: @@ -1260,6 +1269,26 @@ TAO_Marshal_Sequence::decode (CORBA::TypeCode_ptr tc, if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) return CORBA::TypeCode::TRAVERSE_CONTINUE; break; + + case CORBA::tk_objref: + { + size = sizeof (CORBA_Object_ptr); + while (bounds-- && + retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + { + CORBA_Object_ptr ptr; + retval = stream->decode (tc2, &ptr, 0, env); + if (env.exception () != 0) break; + seq->_downcast (value, ptr, env); + if (env.exception () != 0) break; + CORBA::release (ptr); + value += size; + } + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + return retval; + } + break; + default: break; } // end of switch @@ -1269,9 +1298,10 @@ TAO_Marshal_Sequence::decode (CORBA::TypeCode_ptr tc, else return CORBA::TypeCode::TRAVERSE_CONTINUE; } - // error exit - env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); - dmsg ("marshaling TAO_Marshal_Sequence::decode detected error"); + // If an error was detected but no exception was raised then raise a + // marshal exception. + if (env.exception () == 0) + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); return CORBA::TypeCode::TRAVERSE_STOP; } diff --git a/TAO/tao/deep_free.cpp b/TAO/tao/deep_free.cpp index 3e73054bc22..140be7b3dbd 100644 --- a/TAO/tao/deep_free.cpp +++ b/TAO/tao/deep_free.cpp @@ -216,9 +216,16 @@ TAO_Marshal_Struct::deep_free (CORBA::TypeCode_ptr tc, case CORBA::tk_Principal: retval = TAO_Marshal_Principal::deep_free (param, source, dest, env); break; + case CORBA::tk_objref: - retval = TAO_Marshal_ObjRef::deep_free (param, source, dest, env); + { + TAO_Object_Field* field = + ACE_static_cast (TAO_Object_Field*,source); + field->_release (); + retval = CORBA::TypeCode::TRAVERSE_CONTINUE; + } break; + case CORBA::tk_struct: retval = TAO_Marshal_Struct::deep_free (param, source, dest, env); break; diff --git a/TAO/tao/encode.cpp b/TAO/tao/encode.cpp index 53fa33609e9..00b63cca8c7 100644 --- a/TAO/tao/encode.cpp +++ b/TAO/tao/encode.cpp @@ -440,9 +440,19 @@ TAO_Marshal_Struct::encode (CORBA::TypeCode_ptr tc, case CORBA::tk_string: case CORBA::tk_wstring: case CORBA::tk_TypeCode: - case CORBA::tk_objref: retval = stream->encode (param, data, 0, env); break; + + case CORBA::tk_objref: + { + TAO_Object_Field* field = + ACE_static_cast(TAO_Object_Field*, data); + CORBA_Object_ptr ptr = + field->_upcast (); + retval = stream->encode (param, &ptr, 0, env); + } + break; + default: break; } @@ -865,7 +875,6 @@ TAO_Marshal_Sequence::encode (CORBA::TypeCode_ptr tc, case CORBA::tk_any: case CORBA::tk_TypeCode: case CORBA::tk_Principal: - case CORBA::tk_objref: case CORBA::tk_struct: case CORBA::tk_union: case CORBA::tk_string: @@ -885,6 +894,24 @@ TAO_Marshal_Sequence::encode (CORBA::TypeCode_ptr tc, if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) return CORBA::TypeCode::TRAVERSE_CONTINUE; break; + + case CORBA::tk_objref: + { + size = sizeof (CORBA_Object_ptr); + while (bounds-- && + retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + { + CORBA_Object_ptr ptr = + seq->_upcast (value); + retval = stream->encode (tc2, &ptr, 0, env); + if (env.exception () != 0) break; + value += size; + } + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + return retval; + } + break; + default: break; } // end of switch @@ -902,9 +929,10 @@ TAO_Marshal_Sequence::encode (CORBA::TypeCode_ptr tc, return CORBA::TypeCode::TRAVERSE_CONTINUE; } - // error exit - env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); - dmsg ("marshaling TAO_Marshal_Sequence::encode detected error"); + // If an error was detected but no exception was raised then raise a + // marshal exception. + if (env.exception () == 0) + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); return CORBA::TypeCode::TRAVERSE_STOP; } diff --git a/TAO/tao/orbconf.h b/TAO/tao/orbconf.h index 130e754bc24..8685f827c03 100644 --- a/TAO/tao/orbconf.h +++ b/TAO/tao/orbconf.h @@ -225,10 +225,6 @@ #undef major #endif /* major*/ -// TAO has problems encoding/decoding object references inside -// structs. -#define TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - // For Win16, near/far pointers reflect same/other segment addressing. // Of course, ACE doesn't support Win16, so why bother? diff --git a/TAO/tao/varout.cpp b/TAO/tao/varout.cpp new file mode 100644 index 00000000000..33340e2ec6b --- /dev/null +++ b/TAO/tao/varout.cpp @@ -0,0 +1,55 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// varout.cpp +// +// = DESCRIPTION +// Templates for _var and _out types +// +// = AUTHOR +// +// Aniruddha Gokhale +// Carlos O'Ryan +// ============================================================================ + +#if !defined (TAO_VAROUT_C) +#define TAO_VAROUT_C + +#include "tao/varout.h" + +#if !defined (__ACE_INLINE__) +#include "tao/varout.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao, varout, "$Id$") + +template<class T> void +TAO_Object_Field_T<T>::_downcast (CORBA_Object* base_ptr, + CORBA_Environment &env) +{ + CORBA::release (this->ptr_); + this->ptr_ = 0; + this->ptr_ = T::_narrow (base_ptr, env); + if (env.exception () != 0) return; +} + +template<class T> CORBA_Object* +TAO_Object_Field_T<T>::_upcast (void) +{ + return this->ptr_; +} + +template<class T> void +TAO_Object_Field_T<T>::_release (void) +{ + CORBA::release (this->ptr_); + this->ptr_ = 0; +} + +#endif /* TAO_VAROUT_C */ diff --git a/TAO/tao/varout.h b/TAO/tao/varout.h index 5c9d7e3c7f8..96ae1416ffc 100644 --- a/TAO/tao/varout.h +++ b/TAO/tao/varout.h @@ -1,7 +1,6 @@ /* -*- C++ -*- */ // $Id$ - // ============================================================================ // // = LIBRARY @@ -21,6 +20,88 @@ #if !defined (TAO_VAROUT_H) #define TAO_VAROUT_H +class CORBA_Object; + +template <class T> +class TAO_Object_Field_T : public TAO_Object_Field +{ + // = TITLE + // Parametric class to implement structure fields corresponding to + // object references. + // + // = DESCRIPTION + // When an object reference appears in a structure the marshaling + // and demarhsaling of the structure gets complicated: + // the interpreter can only marshal CORBA_Object_ptr when it + // dermarshal it creates on of those objects. + // The downcasting to the right type must be executed by classes + // with compile-time knowledge of the object type. + // The solution addopted in TAO is to create a special manager + // class for that field, +public: + TAO_Object_Field_T (void); + // default constructor + + TAO_Object_Field_T (T* object); + // constructor from a T*, assumes ownership of <object> i.e. it + // *will* release it. + + TAO_Object_Field_T (const TAO_Object_Field_T<T> &); + // copy constructor + + virtual ~TAO_Object_Field_T (void); + // destructor + + TAO_Object_Field_T<T> &operator= (T* object); + // Assignment from a T*, it assumes ownership of <object>. + + TAO_Object_Field_T<T> &operator= (const TAO_Object_Field_T<T> &); + // Assignment operator, in duplicates the underlying objects. + + T* operator-> (void) const; + // smart pointer (const) + + operator const T* &() const; + // cast operator + + operator T* &(); + // cast operator + + // = operations for parameter passing modes + + T* in (void) const; + // for in type parameter + + T* &inout (void); + // for inout type parameter + + T* &out (void); + // for out parameter + + T* _retn (void); + // for return type + + T* ptr (void) const; + // TAO extension for access to the underlying pointer. + + virtual void _downcast (CORBA_Object* base_ptr, + CORBA_Environment& env); + virtual CORBA_Object* _upcast (void); + virtual void _release (void); + // Implement the TAO_Object_Field methods. + +private: + T* ptr_; +}; + +// **************************************************************** +// The following classes are experimental, some of them do *not* +// compile and produce errors in compilers that check templates before +// instantiation time. In the future we may use them to implement +// several classes generated by IDL compiler, possibly reducing the +// complexity of the compiler. +// **************************************************************** +#if 0 template <class T> class TAO_Fixed_var // = TITLE @@ -622,5 +703,18 @@ public: private: T_ptr &ptr_; }; +#endif /* 0 */ + +#if defined (__ACE_INLINE__) +#include "tao/varout.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "tao/varout.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("varout.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ #endif /* TAO_VAROUT_H */ diff --git a/TAO/tao/varout.i b/TAO/tao/varout.i new file mode 100644 index 00000000000..132628d1cf7 --- /dev/null +++ b/TAO/tao/varout.i @@ -0,0 +1,100 @@ +// +// $Id$ +// + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::TAO_Object_Field_T (void) + : ptr_ (0) +{ +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::TAO_Object_Field_T (T* object) + : ptr_ (object) +{ +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::TAO_Object_Field_T (const TAO_Object_Field_T<T>& rhs) + : ptr_ (T::_duplicate (rhs.ptr_)) +{ +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::~TAO_Object_Field_T (void) +{ + CORBA::release (this->ptr_); +} + +template<class T> ACE_INLINE TAO_Object_Field_T<T> & +TAO_Object_Field_T<T>::operator= (T* object) +{ + CORBA::release (this->ptr_); + this->ptr_ = object; + return *this; +} + +template<class T> ACE_INLINE TAO_Object_Field_T<T> & +TAO_Object_Field_T<T>::operator= (const TAO_Object_Field_T<T> &rhs) +{ + if (this != &rhs) + { + CORBA::release (this->ptr_); + this->ptr_ = T::_duplicate (rhs.ptr_); + } + return *this; +} + +template<class T> ACE_INLINE T* +TAO_Object_Field_T<T>::ptr (void) const +{ + return this->ptr_; +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::operator const T* &() const +{ + return this->ptr_; +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::operator T* &() +{ + return this->ptr_; +} + +template<class T> ACE_INLINE T* +TAO_Object_Field_T<T>::operator-> (void) const +{ + return this->ptr_; +} + +template<class T> ACE_INLINE T* +TAO_Object_Field_T<T>::in (void) const +{ + return this->ptr_; +} + +template<class T> ACE_INLINE T* & +TAO_Object_Field_T<T>::inout (void) +{ + return this->ptr_; +} + +template<class T> ACE_INLINE T* & +TAO_Object_Field_T<T>::out (void) +{ + CORBA::release (this->ptr_); + this->ptr_ = 0; + return this->ptr_; +} + +template<class T> ACE_INLINE T* +TAO_Object_Field_T<T>::_retn (void) +{ + // yield ownership of managed obj reference + T* val = this->ptr_; + this->ptr_ = 0; + return val; +} + |