diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-01-19 17:33:09 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-01-19 17:33:09 +0000 |
commit | 460279ae76a5462897352ccf44ecbeb1a8f6f1be (patch) | |
tree | 3bb8d0ca73334d03ab019af5a2b4a9a53cc82732 | |
parent | f19615175f2a732685ae41dcbf0294b2fedcbff8 (diff) | |
download | ATCD-460279ae76a5462897352ccf44ecbeb1a8f6f1be.tar.gz |
ChangeLogTag:Mon Jan 19 11:28:47 1998 Carlos O'Ryan <coryan@cs.wustl.edu>
-rw-r--r-- | TAO/ChangeLog-98c | 5 | ||||
-rw-r--r-- | TAO/TAO-INSTALL.html | 4 | ||||
-rw-r--r-- | TAO/TAO_IDL/VCAUTO.MAK | 1 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_sequence.cpp | 42 | ||||
-rw-r--r-- | TAO/VCAUTO.MAK | 3 | ||||
-rw-r--r-- | TAO/docs/releasenotes/index.html | 11 | ||||
-rw-r--r-- | TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp | 14 | ||||
-rw-r--r-- | TAO/tao/VCAUTO.MAK | 1 | ||||
-rw-r--r-- | TAO/tao/corba.h | 5 | ||||
-rw-r--r-- | TAO/tao/corbacom.h | 3 | ||||
-rw-r--r-- | TAO/tao/orbobj.h | 56 | ||||
-rw-r--r-- | TAO/tao/orbobj.i | 162 | ||||
-rw-r--r-- | TAO/tao/sequence.cpp | 202 | ||||
-rw-r--r-- | TAO/tao/sequence.h | 191 | ||||
-rw-r--r-- | TAO/tao/sequence.i | 89 | ||||
-rw-r--r-- | TAO/tao/sequence_T.cpp | 243 | ||||
-rw-r--r-- | TAO/tao/sequence_T.i | 69 | ||||
-rw-r--r-- | TAO/tests/Cubit/TAO/MT_Cubit/server.cpp | 14 |
18 files changed, 813 insertions, 302 deletions
diff --git a/TAO/ChangeLog-98c b/TAO/ChangeLog-98c index d7ceca8661b..9400d1c1c05 100644 --- a/TAO/ChangeLog-98c +++ b/TAO/ChangeLog-98c @@ -1,3 +1,8 @@ +Mon Jan 19 11:28:47 1998 Carlos O'Ryan <coryan@cs.wustl.edu> + + * Merged changes from main_to_poa_merge_9 up to + main_to_poa_merge_10. + Sun Jan 18 01:04:22 1998 <coryan@MILONGA> * TAO_IDL/be/be_attribute.cpp: diff --git a/TAO/TAO-INSTALL.html b/TAO/TAO-INSTALL.html index e1cb22273f2..4a15a512a86 100644 --- a/TAO/TAO-INSTALL.html +++ b/TAO/TAO-INSTALL.html @@ -32,7 +32,9 @@ undefined and most likely unpredictable and erroneous results. <P> <ol> <li>Set <code>ACE_ROOT</code> environment variable as outlined - in the <a href="../ACE-INSTALL.html">ACE installation + in the <a +href="http://www.cs.wustl.edu/~schmidt/ACE-INSTALL.html">ACE +installation notes</a>.</li> <P> <li>Build and install ACE under <CODE>$ACE_ROOT</CODE>.</li> <P> diff --git a/TAO/TAO_IDL/VCAUTO.MAK b/TAO/TAO_IDL/VCAUTO.MAK index 3095d772741..3aa0d8e38b9 100644 --- a/TAO/TAO_IDL/VCAUTO.MAK +++ b/TAO/TAO_IDL/VCAUTO.MAK @@ -1,3 +1,4 @@ +# TAO/TAO_IDL/ MAK_LIST = tao_idl diff --git a/TAO/TAO_IDL/be/be_visitor_sequence.cpp b/TAO/TAO_IDL/be/be_visitor_sequence.cpp index b49d5b95b68..846cb978a72 100644 --- a/TAO/TAO_IDL/be/be_visitor_sequence.cpp +++ b/TAO/TAO_IDL/be/be_visitor_sequence.cpp @@ -71,17 +71,23 @@ int be_visitor_sequence_ch::visit_sequence (be_sequence *node) switch (node->managed_type ()) { case be_sequence::MNG_OBJREF: // sequence of objrefs - case be_sequence::MNG_STRING: // sequence of objrefs if (node->unbounded ()) - os << "TAO_Unbounded_Managed_Sequence<"; + os << "TAO_Unbounded_Object_Sequence<"; else - os << "TAO_Bounded_Managed_Sequence<"; + os << "TAO_Bounded_Object_Sequence<"; + break; + case be_sequence::MNG_STRING: // sequence of strings + if (node->unbounded ()) + os << "TAO_Unbounded_String_Sequence"; + else + os << "TAO_Bounded_String_Sequence<"; break; default: // not a managed type if (node->unbounded ()) os << "TAO_Unbounded_Sequence<"; else os << "TAO_Bounded_Sequence<"; + break; } @@ -94,13 +100,23 @@ int be_visitor_sequence_ch::visit_sequence (be_sequence *node) -1); } - if (node->unbounded ()) + if (node->managed_type () == be_sequence::MNG_STRING) { - os << " >"; + if (!node->unbounded ()) + { + os << "<" << node->max_size () << ">"; + } } else { - os << ", " << node->max_size () << " >"; + if (node->unbounded ()) + { + os << " >"; + } + else + { + os << ", " << node->max_size () << " >"; + } } os << " " << node->local_name () << ";" << nl; @@ -196,7 +212,7 @@ be_visitor_sequence_base_ch::visit_predefined_type (be_predefined_type *node) switch (node->pt ()) { case AST_PredefinedType::PT_pseudo: - os << "CORBA::Object, TAO_Object_Manager<CORBA::Object> "; + os << "CORBA::Object"; default: os << node->name (); } @@ -223,10 +239,6 @@ be_visitor_sequence_base_ch::visit_interface (be_interface * /* node */) { TAO_OutStream &os = this->stream (); os << this->current_type_->nested_type_name (this->seq_scope ()); - os << ", "; - os << "TAO_Object_Manager<" - << this->current_type_->nested_type_name (this->seq_scope ()) - << "> "; return 0; } @@ -235,22 +247,16 @@ be_visitor_sequence_base_ch::visit_interface_fwd (be_interface_fwd *node) { TAO_OutStream &os = this->stream (); os << this->current_type_->nested_type_name (this->seq_scope ()); - os << ", "; - os << "TAO_Object_Manager<" - << this->current_type_->nested_type_name (this->seq_scope ()) - << "> "; return 0; } int be_visitor_sequence_base_ch::visit_string (be_string * /* node */) { - TAO_OutStream &os = this->stream (); - os << "char*, TAO_String_Manager "; + // NO-OP, we have ad-hoc classes from strings. return 0; } - int be_visitor_sequence_base_ch::visit_structure (be_structure *node) { diff --git a/TAO/VCAUTO.MAK b/TAO/VCAUTO.MAK index e57821b95ee..ca7cb555dca 100644 --- a/TAO/VCAUTO.MAK +++ b/TAO/VCAUTO.MAK @@ -1,4 +1,5 @@ +# TAO/ -DIR_LIST = TAO.dir tao_idl.dir +DIR_LIST = TAO.dir tao_idl.dir tests.dir !INCLUDE <$(ACE_ROOT)\include\makeinclude\VC50_DIR.MAK> diff --git a/TAO/docs/releasenotes/index.html b/TAO/docs/releasenotes/index.html index 55e8f48d634..5d3f405cfeb 100644 --- a/TAO/docs/releasenotes/index.html +++ b/TAO/docs/releasenotes/index.html @@ -212,7 +212,8 @@ Point of contact: <A HREF="mailto:coryan@cs.wustl.edu">Carlos O'Ryan</A> <LI> The current Event Channel is working on TAO, the Scheduling Service still has some problems, -apparently related to the IDL compiler.</LI> +apparently related to sequences of variable sized structures as out +parameters.</LI> <LI> The configuration runs can be done even on the distributed scenario, using @@ -222,7 +223,8 @@ the Real-time "Scheduling Service", which now has an IDL interface.</LI> At run-time (no config runs) there is no need to use the Real-time Scheduling Service, a faster, collocated implementation for the service is available. Obviously the information is generated on the config runs and linked into -the program. Unfortunately the schedule information cannot be +the program. +Unfortunately the schedule information cannot be downloaded from the service right now.</LI> <LI> @@ -260,6 +262,11 @@ but requires a (small) amount of dynamic memory allocation. It could be interesting to "save" the schedule computation in some persistent form, so startup cost are lower too.</LI> +<LI> +The user should have complete control of services collocation, +ACE services for dynamically loaded objects should help in this area, +but we need to add support for NT DLLs in the IDL compiler.</LI> + </UL> <P>For general documentation on the Event Service please read <A HREF="http://www.cs.wustl.edu/~schmidt/oopsla.ps.gz"> diff --git a/TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp b/TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp index fa2e4687412..d21f6c81194 100644 --- a/TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp +++ b/TAO/performance-tests/Cubit/TAO/MT_Cubit/server.cpp @@ -130,14 +130,18 @@ Cubit_Task::create_servants () "implementation object&d\n", i), 2); - CORBA::OctetSeq obj_key; - - obj_key.buffer = (CORBA::Octet *) obj_str; - obj_key.length = obj_key.maximum = ACE_OS::strlen (obj_str); + TAO_opaque obj_key (ACE_OS::strlen (obj_str)); + for (CORBA::ULong i = 0; + i < obj_key.maximum (); + ++i) + { + obj_key[i] = obj_str[i]; + } + obj_key.length (obj_key.maximum ()); CORBA::Object_ptr obj = 0; - if (oa_ptr_->find (obj_key, obj) == -1) + if (this->oa_ptr_->find (obj_key, obj) == -1) ACE_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to locate object with key '%s', %p\n", key), diff --git a/TAO/tao/VCAUTO.MAK b/TAO/tao/VCAUTO.MAK index ec0eb04c66c..28f48c75716 100644 --- a/TAO/tao/VCAUTO.MAK +++ b/TAO/tao/VCAUTO.MAK @@ -1,3 +1,4 @@ +# TAO/tao/ MAK_LIST = TAO diff --git a/TAO/tao/corba.h b/TAO/tao/corba.h index a2081407bb8..0ec14b0a3cf 100644 --- a/TAO/tao/corba.h +++ b/TAO/tao/corba.h @@ -91,6 +91,10 @@ // individual CORBA classes #include "tao/sequence.h" #include "tao/sequence_T.h" + +typedef TAO_Unbounded_Sequence<CORBA::Octet> TAO_opaque; +extern CORBA::TypeCode TC_opaque; + #include "tao/any.h" #include "tao/params.h" @@ -147,7 +151,6 @@ extern TAO_Export int operator== (const TAO::ObjectKey &l, #include "tao/orb_core.i" #include "tao/corbacom.i" -#include "tao/sequence.i" #include "tao/typecode.i" #include "tao/nvlist.i" #include "tao/any.i" diff --git a/TAO/tao/corbacom.h b/TAO/tao/corbacom.h index ceb2aebbd09..9e41ff6fa49 100644 --- a/TAO/tao/corbacom.h +++ b/TAO/tao/corbacom.h @@ -672,9 +672,6 @@ public: }; }; // end of class (namespace) CORBA -typedef TAO_Unbounded_Sequence<CORBA::Octet> TAO_opaque; -extern CORBA::TypeCode TC_opaque; - typedef void (*TAO_Skeleton)(CORBA::ServerRequest &, void *, // object_ptr void *, // context_ptr diff --git a/TAO/tao/orbobj.h b/TAO/tao/orbobj.h index 7fced50cf79..e0ef8b40a38 100644 --- a/TAO/tao/orbobj.h +++ b/TAO/tao/orbobj.h @@ -4,7 +4,7 @@ // // = LIBRARY // TAO -// +// // = FILENAME // orbobj.h // @@ -17,7 +17,7 @@ // // = AUTHOR // Copyright 1994-1995 by Sun Microsystems Inc. -// +// // ============================================================================ #if !defined (TAO_ORBOBJ_H) @@ -48,7 +48,7 @@ public: static CORBA::ORB_ptr _duplicate (CORBA::ORB_ptr orb); // Return a duplicate of <{orb}>. When work with this duplicate is // complete, it should be freed up using <CORBA::release()>. - + static CORBA::ORB_ptr _nil (void); // Returns a pointer to a nil ORB, i.e., an non-existent ORB. This // can be used for initialization or in comparisons. @@ -74,18 +74,18 @@ public: // Of all of these operations, only <run> is currently implemented. // Others require clarification of design or more implementation // than is currently available. - + CORBA::Boolean work_pending (void); // Returns an indication of whether the ORB needs the <{main thread}> to // perform some work. - + int perform_work (ACE_Time_Value * = 0); // If called by the <{main thread}>, this operation performs an // implementation-defined unit of work. Otherwise, it does nothing. // // It is platform-specific how the application and ORB arrange to // use compatible threading primitives. - + int run (ACE_Time_Value *tv = 0); // Instructs the ORB to initialize itself and run its event loop in // the current thread, not returning until the ORB has shut down. @@ -97,7 +97,7 @@ public: // is returned. // // <{Note that this interface differs from the POA specification, - // which is reproduced below:}> + // which is reproduced below:}> // // Returns when the ORB has shut down. If called by the main // thread, it enables the ORB to perform work using the main @@ -204,4 +204,46 @@ private: CORBA_ORB &operator= (const CORBA_ORB &); }; +class CORBA_ORB_var +{ +public: + CORBA_ORB_var (void); // default constructor + CORBA_ORB_var (CORBA::ORB_ptr); + CORBA_ORB_var (const CORBA_ORB_var &); // copy constructor + ~CORBA_ORB_var (void); // destructor + + CORBA_ORB_var &operator= (CORBA::ORB_ptr); + CORBA_ORB_var &operator= (const CORBA_ORB_var &); + CORBA::ORB_ptr operator-> (void) const; + + operator const CORBA::ORB_ptr &() const; + operator CORBA::ORB_ptr &(); + // in, inout, out, _retn + CORBA::ORB_ptr in (void) const; + CORBA::ORB_ptr &inout (void); + CORBA::ORB_ptr &out (void); + CORBA::ORB_ptr _retn (void); + CORBA::ORB_ptr ptr (void) const; + +private: + CORBA::ORB_ptr ptr_; +}; + +class CORBA_ORB_out +{ +public: + CORBA_ORB_out (CORBA::ORB_ptr &); + CORBA_ORB_out (CORBA_ORB_var &); + CORBA_ORB_out (CORBA_ORB_out &); + CORBA_ORB_out &operator= (CORBA_ORB_out &); + CORBA_ORB_out &operator= (const CORBA_ORB_var &); + CORBA_ORB_out &operator= (CORBA::ORB_ptr); + operator CORBA::ORB_ptr &(); + CORBA::ORB_ptr &ptr (void); + CORBA::ORB_ptr operator-> (void); + +private: + CORBA::ORB_ptr &ptr_; +}; + #endif /* TAO_ORBOBJ_H */ diff --git a/TAO/tao/orbobj.i b/TAO/tao/orbobj.i index 2bd0967e784..e7c96b1481f 100644 --- a/TAO/tao/orbobj.i +++ b/TAO/tao/orbobj.i @@ -52,8 +52,168 @@ ACE_INLINE void CORBA_ORB::shutdown (CORBA::Boolean wait_for_completion) { ACE_UNUSED_ARG (wait_for_completion); - + this->should_shutdown_ = CORBA::B_TRUE; TAO_ORB_Core_instance ()->reactor ()->wakeup_all_threads (); return; } + +// ************************************************************* +// Inline operations for class CORBA_ORB_var +// ************************************************************* + +ACE_INLINE +CORBA_ORB_var::CORBA_ORB_var (void) // default constructor + : ptr_ (CORBA_ORB::_nil ()) +{} + +ACE_INLINE +CORBA_ORB_var::CORBA_ORB_var (CORBA::ORB_ptr p) + : ptr_ (p) +{} + +ACE_INLINE CORBA::ORB_ptr +CORBA_ORB_var::ptr (void) const +{ + return this->ptr_; +} + +ACE_INLINE +CORBA_ORB_var::CORBA_ORB_var (const CORBA_ORB_var &p) // copy constructor + : ptr_ (CORBA_ORB::_duplicate (p.ptr ())) +{} + +ACE_INLINE +CORBA_ORB_var::~CORBA_ORB_var (void) // destructor +{ + CORBA::release (this->ptr_); +} + +ACE_INLINE CORBA_ORB_var & +CORBA_ORB_var::operator= (CORBA::ORB_ptr p) +{ + CORBA::release (this->ptr_); + this->ptr_ = p; + return *this; +} + +ACE_INLINE CORBA_ORB_var & +CORBA_ORB_var::operator= (const CORBA_ORB_var &p) +{ + if (this != &p) + { + CORBA::release (this->ptr_); + this->ptr_ = CORBA_ORB::_duplicate (p.ptr ()); + } + return *this; +} + +ACE_INLINE +CORBA_ORB_var::operator const CORBA::ORB_ptr &() const // cast +{ + return this->ptr_; +} + +ACE_INLINE +CORBA_ORB_var::operator CORBA::ORB_ptr &() // cast +{ + return this->ptr_; +} + +ACE_INLINE CORBA::ORB_ptr +CORBA_ORB_var::operator-> (void) const +{ + return this->ptr_; +} + +ACE_INLINE CORBA::ORB_ptr +CORBA_ORB_var::in (void) const +{ + return this->ptr_; +} + +ACE_INLINE CORBA::ORB_ptr & +CORBA_ORB_var::inout (void) +{ + return this->ptr_; +} + +ACE_INLINE CORBA::ORB_ptr & +CORBA_ORB_var::out (void) +{ + CORBA::release (this->ptr_); + this->ptr_ = CORBA_ORB::_nil (); + return this->ptr_; +} + +ACE_INLINE CORBA::ORB_ptr +CORBA_ORB_var::_retn (void) +{ + // yield ownership of managed obj reference + CORBA::ORB_ptr val = this->ptr_; + this->ptr_ = CORBA_ORB::_nil (); + return val; +} + +// ************************************************************* +// Inline operations for class CORBA_ORB_out +// ************************************************************* + +ACE_INLINE +CORBA_ORB_out::CORBA_ORB_out (CORBA::ORB_ptr &p) + : ptr_ (p) +{ + this->ptr_ = CORBA_ORB::_nil (); +} + +ACE_INLINE +CORBA_ORB_out::CORBA_ORB_out (CORBA_ORB_var &p) // constructor from _var + : ptr_ (p.out ()) +{ + CORBA::release (this->ptr_); + this->ptr_ = CORBA_ORB::_nil (); +} + +ACE_INLINE +CORBA_ORB_out::CORBA_ORB_out (CORBA_ORB_out &p) // copy constructor + : ptr_ (p.ptr_) +{} + +ACE_INLINE CORBA_ORB_out & +CORBA_ORB_out::operator= (CORBA_ORB_out &p) +{ + this->ptr_ = p.ptr_; + return *this; +} + +ACE_INLINE CORBA_ORB_out & +CORBA_ORB_out::operator= (const CORBA_ORB_var &p) +{ + this->ptr_ = CORBA_ORB::_duplicate (p.ptr ()); + return *this; +} + +ACE_INLINE CORBA_ORB_out & +CORBA_ORB_out::operator= (CORBA::ORB_ptr p) +{ + this->ptr_ = p; + return *this; +} + +ACE_INLINE +CORBA_ORB_out::operator CORBA::ORB_ptr &() // cast +{ + return this->ptr_; +} + +ACE_INLINE CORBA::ORB_ptr & +CORBA_ORB_out::ptr (void) // ptr +{ + return this->ptr_; +} + +ACE_INLINE CORBA::ORB_ptr +CORBA_ORB_out::operator-> (void) +{ + return this->ptr_; +} diff --git a/TAO/tao/sequence.cpp b/TAO/tao/sequence.cpp index b892f8e92c2..746ec881c06 100644 --- a/TAO/tao/sequence.cpp +++ b/TAO/tao/sequence.cpp @@ -4,6 +4,10 @@ #include "tao/corba.h" +#if !defined (__ACE_INLINE__) +#include "tao/sequence.i" +#endif /* __ACE_INLINE__ */ + // ************************************************************* // Operations for class TAO_Base_Sequence // ************************************************************* @@ -12,21 +16,14 @@ TAO_Base_Sequence::~TAO_Base_Sequence (void) { } -// ************************************************************* -// Operations for class TAO_String_Manager -// ************************************************************* - -// destructor -TAO_String_Manager::~TAO_String_Manager (void) +void TAO_Base_Sequence::_shrink_buffer (CORBA::ULong, CORBA::ULong) { + // default is no op. } -// copy constructor -TAO_String_Manager::TAO_String_Manager(const TAO_String_Manager &rhs) -{ - *this->ptr_ = CORBA::string_dup (*rhs.ptr_); - this->release_ = 1; -} +// ************************************************************* +// Operations for class TAO_String_Manager +// ************************************************************* // assignment TAO_String_Manager& @@ -36,58 +33,177 @@ TAO_String_Manager::operator=(const TAO_String_Manager &rhs) return *this; if (this->release_) // need to free old one - CORBA::string_free (*this->ptr_); - - *this->ptr_ = CORBA::string_dup (*rhs.ptr_); - this->release_ = 1; + { + CORBA::string_free (*this->ptr_); + *this->ptr_ = CORBA::string_dup (*rhs.ptr_); + } + else + { + *this->ptr_ = *rhs.ptr_; + } return *this; } // assignment from char* TAO_String_Manager & -TAO_String_Manager::operator= (char * p) +TAO_String_Manager::operator= (const char * p) { - if (this->release_) // need to free old one - CORBA::string_free (*this->ptr_); + if (this->release_) + { + CORBA::string_free (*this->ptr_); + *this->ptr_ = CORBA::string_dup (p); + } + else + { + *this->ptr_ = ACE_const_cast(char*,p); + } + return *this; +} - *this->ptr_ = p; // no copy - this->release_ = 0; +// ************************************************************* - return *this; +// constructor for unbounded seq +TAO_Unbounded_String_Sequence:: +TAO_Unbounded_String_Sequence (CORBA::ULong maximum) + : TAO_Unbounded_Base_Sequence (maximum, + TAO_Unbounded_String_Sequence::allocbuf (maximum)) +{ } -TAO_String_Manager & -TAO_String_Manager::operator= (const char * p) +TAO_Unbounded_String_Sequence:: +TAO_Unbounded_String_Sequence (const TAO_Unbounded_String_Sequence &seq) + : TAO_Unbounded_Base_Sequence (seq) { - if (this->release_) // need to free old one + this->buffer_ = + TAO_Unbounded_String_Sequence::allocbuf (this->maximum_); + + char* *tmp1 = ACE_reinterpret_cast(char* *,this->buffer_); + char* *tmp2 = ACE_reinterpret_cast(char* *,seq.buffer_); + for (CORBA::ULong i = 0; i < seq.length_; ++i) + tmp1 [i] = CORBA::string_dup (tmp2 [i]); + + this->release_ = 1; +} + +TAO_Unbounded_String_Sequence::~TAO_Unbounded_String_Sequence (void) +{ + this->_deallocate_buffer (); +} + +TAO_Unbounded_String_Sequence& +TAO_Unbounded_String_Sequence:: +operator= (const TAO_Unbounded_String_Sequence &seq) +{ + if (this == &seq) + return *this; + + if (this->release_) { - CORBA::string_free (*this->ptr_); - *this->ptr_ = CORBA::string_dup (p); - this->release_ = 1; + char* *tmp = ACE_reinterpret_cast(char* *,this->buffer_); + for (CORBA::ULong i = 0; i < this->length_; ++i) + { + CORBA::string_free (tmp[i]); + } + if (this->maximum_ < seq.maximum_) + { + this->buffer_ = + TAO_Unbounded_String_Sequence::allocbuf (seq.maximum_); + } } else { - *this->ptr_ = (char *)p; - this->release_ = 0; + this->buffer_ = + TAO_Unbounded_String_Sequence::allocbuf (this->maximum_); } + + char* *tmp1 = ACE_reinterpret_cast(char* *,this->buffer_); + char* *tmp2 = ACE_reinterpret_cast(char* *,seq.buffer_); + CORBA::ULong i=0; + for (; i < seq.length_; ++i) + tmp1 [i] = CORBA::string_dup (tmp2 [i]); + return *this; } -// mapping for variable size - out -char *& -TAO_String_Manager::out (void) +char* * +TAO_Unbounded_String_Sequence::allocbuf (CORBA::ULong nelems) { - if (this->release_) - CORBA::string_free (*this->ptr_); - *this->ptr_ = 0; - return *this->ptr_; + char* *buf = new char*[nelems]; + for (CORBA::ULong i=0; i < nelems; i++) + buf[i] = 0; + return buf; +} + +void +TAO_Unbounded_String_Sequence::freebuf (char* *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. + + char* *tmp = ACE_reinterpret_cast (char**,buffer); + delete[] tmp; +} + +void +TAO_Unbounded_String_Sequence::_allocate_buffer (CORBA::ULong length) +{ + char* *tmp; + ACE_NEW (tmp, char* [length]); + + if (this->buffer_ != 0) + { + char* *old = ACE_reinterpret_cast(char**,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] = CORBA::string_dup (old[i]); + else + tmp [i] = old[i]; + } + if (this->release_) + delete[] old; + } + this->buffer_ = tmp; +} + +void +TAO_Unbounded_String_Sequence::_deallocate_buffer (void) +{ + if (this->buffer_ == 0 || this->release_ == 0) + return; + char* *tmp = ACE_reinterpret_cast (char**,this->buffer_); + for (CORBA::ULong i = 0; + i < this->length_; + ++i) + { + CORBA::string_free (tmp[i]); + } + delete[] tmp; + this->buffer_ = 0; } -// _retn (gives up ownership) -char * -TAO_String_Manager::_retn (void) +void +TAO_Unbounded_String_Sequence::_shrink_buffer (CORBA::ULong nl, + CORBA::ULong ol) { - char *tmp = *this->ptr_; - *this->ptr_ = 0; - return tmp; + char* *tmp = ACE_reinterpret_cast (char**,this->buffer_); + for (CORBA::ULong i = ol; i < nl; ++i) + CORBA::string_free (tmp[i]); } diff --git a/TAO/tao/sequence.h b/TAO/tao/sequence.h index ca9f24a069f..1437048dad8 100644 --- a/TAO/tao/sequence.h +++ b/TAO/tao/sequence.h @@ -26,7 +26,6 @@ class TAO_Export TAO_Base_Sequence // This class provides a common interface for all IDL sequences, // hence the interpreted marshal engine can manipulate them in a // type safe manner. - // public: friend class TAO_Marshal_Sequence; // We give access to TAO_Marshal_Sequence, this allows a safe yet @@ -38,9 +37,6 @@ public: CORBA::ULong maximum (void) const; // return the maximum length of the sequence - // void length (CORBA::ULong length); - // set the length - virtual void _allocate_buffer (CORBA::ULong length) = 0; // Ensure that the buffer contains space for at least <length> // elements. The constructor must be called for any new elements, @@ -51,6 +47,13 @@ public: virtual void _deallocate_buffer (void) = 0; // Must deallocate the buffer and then set it to zero. + virtual void _shrink_buffer (CORBA::ULong new_length, + CORBA::ULong old_length); + // Some sequences (of objects and strings) require some cleanup if + // the sequence is shrunk. The spec requires the destructor to + // release the objects only from position <0> to <length-1>; so + // shrink and then delete could result in a memory leak. + protected: TAO_Base_Sequence (void); // Default constructor. @@ -100,8 +103,13 @@ class TAO_Export TAO_Unbounded_Base_Sequence : public TAO_Base_Sequence // generated code in the templates. public: void length (CORBA::ULong length); - // set the length, for this sequences this call increases the - // capacity on demand. + // = SPEC {16.11.2} + // For an unbounded sequence, setting the length to a larger value + // than the current length may reallocate the sequence + // data. Reallocation is conceptually equivalent to creating a new + // sequence of the desired new length, copying the old sequence + // elements zero through length into the new sequence, and then + // assigning the old sequence to be the same as the new sequence. CORBA::ULong length (void) const; // return the current length, it cannot go into the base class due @@ -161,9 +169,6 @@ protected: /****************************************************************/ -template<class T, class Manager> class TAO_Unbounded_Managed_Sequence; -template<class T, class Manager, CORBA::ULong MAX> class TAO_Bounded_Managed_Sequence; - class TAO_Export TAO_String_Manager { // = TITLE @@ -179,30 +184,25 @@ class TAO_Export TAO_String_Manager // for the sequence as a whole. // The difference wrt Object_Manager is that strings are // duplicated using CORBA::string_copy() as opposed to - // T::_duplicate(). + // T::_duplicate(), and released using CORBA::string_free() + // instead of CORBA::release() // // This class implements the generic string manager and is used to // instantiate the proper sequence types. // - // = NOTES - // It has been proposed that the class should be parametric on - // both T and T_ptr, IMHO this is no necesary: though the IDL spec - // says that T_ptr *could* map to a type different to T* in the - // particular case of TAO it does map to <T*>. - // public: - friend class TAO_Unbounded_Managed_Sequence<char*,TAO_String_Manager>; + friend class TAO_Unbounded_String_Sequence; - // @@ Use partial template specialization here to give access only - // to the right kind of sequence. + // @@ Giving friendship to a template is not implemented on several + // compilers: // friend template<CORBA::ULong MAX> - // class TAO_Bounded_Managed_Sequence<char*,TAO_String_Manager,MAX>; + // class TAO_Bounded_String_Sequence<TAO_String_Manager,MAX>; TAO_String_Manager (const TAO_String_Manager &); // copy constructor - TAO_String_Manager (char **buffer, CORBA::Boolean release); + TAO_String_Manager (char* *buffer, CORBA::Boolean release); // constructor from address of an element ~TAO_String_Manager (void); @@ -211,43 +211,140 @@ public: TAO_String_Manager &operator= (const TAO_String_Manager&); // assignment from another managed type - TAO_String_Manager &operator= (char *); - // assignment from a char* - TAO_String_Manager &operator= (const char *); // assignment from a constant char* operator const char*() const; // cast (read-only) - operator char *(); - // cast - - char &operator[] (CORBA::ULong index); - // accessor - - const char* &operator[] (CORBA::ULong index) const; - // read-only accessor +private: + char* *ptr_; + // address of string element from the parent's buffer - // in, inout, out, _retn - const char *in (void) const; - // returns the underlying string + CORBA::Boolean release_; + // control memory managment semantics. +}; - char *&inout (void); - // returns a reference to the underlying string for in arguments +class TAO_Unbounded_String_Sequence : public TAO_Unbounded_Base_Sequence +{ + // =TITLE + // 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. + + // = 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. + // +public: + typedef TAO_String_Manager Manager; - char *&out (void); - // used for out arguments + // =operations for the Unbounded_ObjectSequence - char *_retn (void); - // gives up ownership, used for return types. + TAO_Unbounded_String_Sequence (void); + // {orbos/97-05-15:16.8} + // The default constructor initializes object reference members to + // appropriately typed nil object references and string members to + // NULL; all other members are initialized via their default + // constructors. + // + // {orbos/97-05-15:16.11} + // For both bounded and unbounded sequences, the default constructor + // (as shown in the example above) sets the sequence length equal to + // 0. + + TAO_Unbounded_String_Sequence (CORBA::ULong maximum); + // Unbounded sequences provide a constructor that allows only the + // initial value of the maximum length to be set (the ``maximum + // constructor'' shown in the example above). This allows + // applications to control how much buffer space is initially + // allocated by the sequence. This constructor also sets the length + // to 0 and the release flag to TRUE. + + TAO_Unbounded_String_Sequence (CORBA::ULong maximum, + CORBA::ULong length, + char* *data, + CORBA::Boolean release=0); + // The ``T *data'' constructor (as shown in the example above) + // allows the length and contents of a bounded or unbounded sequence + // to be set. For unbounded sequences, it also allows the initial + // value of the maximum length to be set. For this constructor, + // ownership of the contents vector is determined by the release + // parameter---FALSE means the caller owns the storage, while TRUE + // means that the sequence assumes ownership of the storage. + // If release is TRUE, the contents vector must have been allocated + // using the sequence allocbuf function, and the sequence will pass + // it to freebuf when finished with it. + + TAO_Unbounded_String_Sequence(const TAO_Unbounded_String_Sequence&); + // The copy constructor performs a deep copy from the existing + // structure to create a new structure, including calling _duplicate + // on all object reference members and performing the necessary + // heap allocations for all string members. + // + // The copy constructor creates a new sequence with the same maximum + // and length as the given sequence, copies each of its current + // elements (items zero through length-1), and sets the release + // flag to TRUE. + + ~TAO_Unbounded_String_Sequence (void); + // The destructor releases all object reference memebrs and frees + // all string members. + + TAO_Unbounded_String_Sequence &operator= (const TAO_Unbounded_String_Sequence &); + // The assignment operator first releases all object reference + // members and frees all string members, and then performs a + // deepcopy to create a new structure. + // + // The assignment operator deepcopies its parameter, releasing + // old storage if necessary. It behaves as if the original sequence + // is destroyed via its destructor and then the source sequence + // copied using the copy constructor. If release=TRUE, the + // destructor destroys each of the current elements (items zero + // through length--1). + // For an unbounded sequence, if a reallocation is necessary due to + // a change in the length and the sequence was created using the + // release=TRUE parameter in its constructor, the sequence will + // deallocate the old storage. If release is FALSE under these + // circumstances, old storage will not be freed before the + // reallocation is performed. After reallocation, the release flag + // is always set to TRUE. + + Manager operator[] (CORBA::ULong index) const; + // read-write accessor + + static char* *allocbuf (CORBA::ULong); + // The allocbuf function allocates a vector of T elements that can + // be passed to the T *data constructor. The length of the vector is + // given by the nelems function argument. The allocbuf function + // initializes each element using its default constructor, except + // for strings, which are initialized to null pointers, and object + // references, which are initialized to suitably typed nil object + // references. A null pointer is returned if allocbuf for some + // reason cannot allocate the requested vector. Vectors allocated by + // allocbuf should be freed using the freebuf function. + + static void freebuf (char* *); + // 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. + + virtual void _allocate_buffer (CORBA::ULong length); + virtual void _deallocate_buffer (void); + virtual void _shrink_buffer (CORBA::ULong new_length, + CORBA::ULong old_length); +}; -private: - char **ptr_; - // address of string element from the parent's buffer - CORBA::Boolean release_; - // based on parent's release flag -}; +#if defined (__ACE_INLINE__) +#include "tao/sequence.i" +#endif /* __ACE_INLINE__ */ #endif /* TAO_SEQUENCE_H */ diff --git a/TAO/tao/sequence.i b/TAO/tao/sequence.i index 5be4f3bae3f..9b728b899c5 100644 --- a/TAO/tao/sequence.i +++ b/TAO/tao/sequence.i @@ -73,30 +73,6 @@ TAO_Base_Sequence::maximum (void) const return this->maximum_; } -#if 0 -ACE_INLINE void -TAO_Base_Sequence::length (CORBA::ULong length) -{ - if (length > this->maximum_) - { - if (this->_bounded ()) - { - // @@ TODO maybe we should throw? - return; - } - this->_allocate_buffer (length); - this->maximum_ = length; - } - this->length_ = length; -} - -ACE_INLINE CORBA::ULong -TAO_Base_Sequence::length (void) const -{ - return this->length_; -} -#endif - // **************************************************************** ACE_INLINE @@ -136,10 +112,14 @@ TAO_Unbounded_Base_Sequence::length (CORBA::ULong length) this->_allocate_buffer (length); this->maximum_ = length; } + else + { + this->_shrink_buffer (length, this->length_); + } this->length_ = length; } - +// **************************************************************** ACE_INLINE TAO_Bounded_Base_Sequence::TAO_Bounded_Base_Sequence (void) @@ -177,5 +157,64 @@ TAO_Bounded_Base_Sequence::length (CORBA::ULong length) { return; } + else + { + this->_shrink_buffer (length, this->length_); + } this->length_ = length; } + +// **************************************************************** + +ACE_INLINE +TAO_String_Manager::TAO_String_Manager(char** buffer, + CORBA::Boolean release) + : ptr_ (buffer), + release_ (release) +{ +} + +ACE_INLINE +TAO_String_Manager::TAO_String_Manager(const TAO_String_Manager &rhs) + : ptr_ (rhs.ptr_), + release_ (rhs.release_) +{ +} + +ACE_INLINE +TAO_String_Manager::~TAO_String_Manager (void) +{ +} + +ACE_INLINE +TAO_String_Manager::operator const char* (void) const +{ + return *this->ptr_; +} + +// **************************************************************** + +//default constructor +ACE_INLINE +TAO_Unbounded_String_Sequence::TAO_Unbounded_String_Sequence (void) +{ +} + +ACE_INLINE +TAO_Unbounded_String_Sequence:: +TAO_Unbounded_String_Sequence (CORBA::ULong maximum, + CORBA::ULong length, + char* *value, + CORBA::Boolean release) + : TAO_Unbounded_Base_Sequence (maximum, length, value, release) +{ +} + +ACE_INLINE TAO_Unbounded_String_Sequence::Manager +TAO_Unbounded_String_Sequence::operator[] (CORBA::ULong index) const +{ + ACE_ASSERT (index < this->maximum_); + char** tmp = ACE_reinterpret_cast (char**, this->buffer_); + return Manager (tmp + index, this->release_); +} + diff --git a/TAO/tao/sequence_T.cpp b/TAO/tao/sequence_T.cpp index b79392b29d0..efa04fdb964 100644 --- a/TAO/tao/sequence_T.cpp +++ b/TAO/tao/sequence_T.cpp @@ -150,14 +150,14 @@ TAO_Object_Manager<T>::~TAO_Object_Manager (void) template <class T> TAO_Object_Manager<T>::TAO_Object_Manager (const TAO_Object_Manager &rhs) + : ptr_ (rhs.ptr_), + release_ (rhs.release_) { - this->ptr_ = rhs.ptr_; - this->release_ = rhs.release_; } template <class T> TAO_Object_Manager<T>& -TAO_Object_Manager<T>::operator= (const TAO_Object_Manager &rhs) +TAO_Object_Manager<T>::operator= (const TAO_Object_Manager<T> &rhs) { if (this == &rhs) return *this; @@ -179,42 +179,44 @@ TAO_Object_Manager<T>::operator=(T* p) return *this; } -// mapping for variable size -template <class T> T* & -TAO_Object_Manager<T>::out (void) -{ - if (this->release_) - CORBA::release (*this->ptr_); - *this->ptr_ = T::_nil (); - return *this->ptr_; -} - -template <class T> T* -TAO_Object_Manager<T>::_retn (void) -{ - T* tmp = *this->ptr_; - *this->ptr_ = T::_nil (); - return tmp; -} - // ************************************************************* -// Operations for class TAO_Unbounded_Managed_Sequence +// Operations for class TAO_Unbounded_Object_Sequence // ************************************************************* -template<class T, class Manager> -TAO_Unbounded_Managed_Sequence<T,Manager>::~TAO_Unbounded_Managed_Sequence (void) +// constructor for unbounded seq +template <class T> +TAO_Unbounded_Object_Sequence<T>:: +TAO_Unbounded_Object_Sequence (CORBA::ULong maximum) + : TAO_Unbounded_Base_Sequence (maximum, + TAO_Unbounded_Object_Sequence<T>::allocbuf (maximum)) { - this->_deallocate_buffer (); } // copy constructor -template <class T, class Manager> -TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence -(const TAO_Unbounded_Managed_Sequence<T,Manager> &seq) +template <class T> +TAO_Unbounded_Object_Sequence<T>:: +TAO_Unbounded_Object_Sequence (const TAO_Unbounded_Object_Sequence<T> &seq) : TAO_Unbounded_Base_Sequence (seq) { - this->buffer_ = TAO_Unbounded_Managed_Sequence<T,Manager>:: - allocbuf (this->maximum_); + if (this->release_) + { + T* *tmp = ACE_reinterpret_cast(T* *,this->buffer_); + for (CORBA::ULong i = 0; i < this->length_; ++i) + { + CORBA::release (tmp[i]); + } + if (this->maximum_ < seq.maximum_) + { + this->buffer_ = + TAO_Unbounded_Object_Sequence<T>::allocbuf (seq.maximum_); + } + } + else + { + this->buffer_ = + TAO_Unbounded_Object_Sequence<T>::allocbuf (this->maximum_); + } + T* *tmp1 = ACE_reinterpret_cast(T* *,this->buffer_); T* *tmp2 = ACE_reinterpret_cast(T* *,seq.buffer_); for (CORBA::ULong i=0; i < seq.length_; i++) @@ -222,18 +224,33 @@ TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence } // assignment operator -template <class T, class Manager> -TAO_Unbounded_Managed_Sequence<T,Manager>& -TAO_Unbounded_Managed_Sequence<T,Manager>::operator= -(const TAO_Unbounded_Managed_Sequence<T,Manager> &seq) +template <class T> +TAO_Unbounded_Object_Sequence<T>& +TAO_Unbounded_Object_Sequence<T>:: +operator= (const TAO_Unbounded_Object_Sequence<T> &seq) { - if (this == &seq) return *this; + if (this == &seq) + return *this; + if (this->release_) - { - T* *tmp = ACE_reinterpret_cast (T* *,this->buffer_); - TAO_Unbounded_Managed_Sequence<T,Manager>::freebuf (tmp, - this->maximum_); - } + { + T* *tmp = ACE_reinterpret_cast(T* *,this->buffer_); + for (CORBA::ULong i = 0; i < this->length_; ++i) + { + CORBA::release (tmp[i]); + } + if (this->maximum_ < seq.maximum_) + { + this->buffer_ = + TAO_Unbounded_Object_Sequence<T>::allocbuf (seq.maximum_); + } + } + else + { + this->buffer_ = + TAO_Unbounded_Object_Sequence<T>::allocbuf (this->maximum_); + } + T* *tmp1 = ACE_reinterpret_cast(T* *,this->buffer_); T* *tmp2 = ACE_reinterpret_cast(T* *,seq.buffer_); for (CORBA::ULong i=0; i < seq.length_; i++) @@ -241,27 +258,39 @@ TAO_Unbounded_Managed_Sequence<T,Manager>::operator= return *this; } -template <class T, class Manager> T* * -TAO_Unbounded_Managed_Sequence<T,Manager>::allocbuf (CORBA::ULong nelems) +template <class T> T* * +TAO_Unbounded_Object_Sequence<T>::allocbuf (CORBA::ULong nelems) { - T* *buf = new T*[nelems]; // allocate from heap + T* *buf = new T*[nelems]; for (CORBA::ULong i=0; i < nelems; i++) - buf[i] = T::_nil (); + buf[i] = T::_nil (); return buf; } -template <class T, class Manager> void -TAO_Unbounded_Managed_Sequence<T,Manager>::freebuf (T* *seq, - CORBA::ULong nelems) +template <class T> void +TAO_Unbounded_Object_Sequence<T>::freebuf (T* *buffer) { - if (!seq) return; // null sequence - for (CORBA::ULong i=0; i < nelems; i++) - CORBA::release (seq[i]); - TAO_Unbounded_Managed_Sequence<T,Manager>::freebuf (seq); + 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. + + T* *tmp = ACE_reinterpret_cast (T**,buffer); + delete[] tmp; } -template<class T, class Manager> -void TAO_Unbounded_Managed_Sequence<T,Manager>::_allocate_buffer (CORBA::ULong length) +template<class T> +void TAO_Unbounded_Object_Sequence<T>::_allocate_buffer (CORBA::ULong length) { T* *tmp; ACE_NEW (tmp, T* [length]); @@ -271,42 +300,63 @@ void TAO_Unbounded_Managed_Sequence<T,Manager>::_allocate_buffer (CORBA::ULong l T* *old = ACE_reinterpret_cast(T**,this->buffer_); for (CORBA::ULong i = 0; i < this->length_; ++i) { - tmp [i] = T::_duplicate (old[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]; } - delete[] old; + if (this->release_) + delete[] old; } this->buffer_ = tmp; } -template<class T, class Manager> -void TAO_Unbounded_Managed_Sequence<T,Manager>::_deallocate_buffer (void) +template<class T> +void TAO_Unbounded_Object_Sequence<T>::_deallocate_buffer (void) { if (this->buffer_ == 0 || this->release_ == 0) return; T* *tmp = ACE_reinterpret_cast (T**,this->buffer_); - // XXXASG: Do we release each object here? - // @@ TODO add static methods to Manager to release each object. + for (CORBA::ULong i = 0; + i < this->length_; + ++i) + { + CORBA::release (tmp[i]); + } delete[] tmp; this->buffer_ = 0; } +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_); + for (CORBA::ULong i = ol; i < nl; ++i) + CORBA::release (tmp[i]); +} + // ************************************************************* -// Operations for class TAO_Bounded_Managed_Sequence +// Operations for class TAO_Bounded_Object_Sequence // ************************************************************* -template<class T, class Manager, CORBA::ULong MAX> -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::~TAO_Bounded_Managed_Sequence (void) +template<class T, CORBA::ULong MAX> +TAO_Bounded_Object_Sequence<T,MAX>::~TAO_Bounded_Object_Sequence (void) { this->_deallocate_buffer (); } -// copy constructor -template <class T, class Manager, CORBA::ULong MAX> -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::TAO_Bounded_Managed_Sequence -(const TAO_Bounded_Managed_Sequence<T,Manager,MAX> &seq) - : TAO_Unbounded_Base_Sequence (seq) +template <class T, CORBA::ULong MAX> +TAO_Bounded_Object_Sequence<T,MAX>:: +TAO_Bounded_Object_Sequence (const TAO_Bounded_Object_Sequence<T,MAX> &seq) + : TAO_Bounded_Base_Sequence (seq) { - this->buffer_ = TAO_Bounded_Managed_Sequence<T,Manager,MAX>:: + this->buffer_ = TAO_Bounded_Object_Sequence<T,MAX>:: allocbuf (this->maximum_); T* *tmp1 = ACE_reinterpret_cast(T* *,this->buffer_); T* *tmp2 = ACE_reinterpret_cast(T* *,seq.buffer_); @@ -315,18 +365,18 @@ TAO_Bounded_Managed_Sequence<T,Manager,MAX>::TAO_Bounded_Managed_Sequence } // assignment operator -template <class T, class Manager, CORBA::ULong MAX> -TAO_Bounded_Managed_Sequence<T,Manager,MAX>& -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::operator= -(const TAO_Bounded_Managed_Sequence<T,Manager,MAX> &seq) +template <class T, CORBA::ULong MAX> +TAO_Bounded_Object_Sequence<T,MAX>& +TAO_Bounded_Object_Sequence<T,MAX>::operator= +(const TAO_Bounded_Object_Sequence<T,MAX> &seq) { - if (this == &seq) return *this; + if (this == &seq) + return *this; if (this->release_) - { - T* *tmp = ACE_reinterpret_cast (T* *,this->buffer_); - TAO_Bounded_Managed_Sequence<T,Manager,MAX>::freebuf (tmp, - this->maximum_); - } + { + T* *tmp = ACE_reinterpret_cast (T* *,this->buffer_); + TAO_Bounded_Object_Sequence<T,MAX>::freebuf (tmp); + } T* *tmp1 = ACE_reinterpret_cast(T* *,this->buffer_); T* *tmp2 = ACE_reinterpret_cast(T* *,seq.buffer_); for (CORBA::ULong i=0; i < seq.length_; i++) @@ -334,27 +384,17 @@ TAO_Bounded_Managed_Sequence<T,Manager,MAX>::operator= return *this; } -template <class T, class Manager, CORBA::ULong MAX> T* * -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::allocbuf (CORBA::ULong nelems) +template <class T, CORBA::ULong MAX> T* * +TAO_Bounded_Object_Sequence<T,MAX>::allocbuf (CORBA::ULong nelems) { T* *buf = new T*[nelems]; // allocate from heap for (CORBA::ULong i=0; i < nelems; i++) - buf[i] = T::_nil (); + buf[i] = T::_nil (); return buf; } -template <class T, class Manager, CORBA::ULong MAX> void -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::freebuf (T* *seq, - CORBA::ULong nelems) -{ - if (!seq) return; // null sequence - for (CORBA::ULong i=0; i < nelems; i++) - CORBA::release (seq[i]); - TAO_Bounded_Managed_Sequence<T,Manager,MAX>::freebuf (seq); -} - -template<class T, class Manager, CORBA::ULong MAX> void -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::_allocate_buffer (CORBA::ULong length) +template<class T, CORBA::ULong MAX> void +TAO_Bounded_Object_Sequence<T,MAX>::_allocate_buffer (CORBA::ULong length) { T* *tmp; ACE_NEW (tmp, T* [length]); @@ -363,16 +403,14 @@ TAO_Bounded_Managed_Sequence<T,Manager,MAX>::_allocate_buffer (CORBA::ULong leng { T* *old = ACE_reinterpret_cast(T**,this->buffer_); for (CORBA::ULong i = 0; i < this->length_; ++i) - { - tmp [i] = T::_duplicate (old[i]); - } + tmp [i] = old[i]; delete[] old; } this->buffer_ = tmp; } -template<class T, class Manager, CORBA::ULong MAX> -void TAO_Bounded_Managed_Sequence<T,Manager,MAX>::_deallocate_buffer (void) +template<class T, CORBA::ULong MAX> +void TAO_Bounded_Object_Sequence<T,MAX>::_deallocate_buffer (void) { if (this->buffer_ == 0 || this->release_ == 0) return; @@ -383,4 +421,13 @@ void TAO_Bounded_Managed_Sequence<T,Manager,MAX>::_deallocate_buffer (void) this->buffer_ = 0; } +template<class T, CORBA::ULong MAX> void +TAO_Bounded_Object_Sequence<T,MAX>::_shrink_buffer (CORBA::ULong nl, + CORBA::ULong ol) +{ + T* *tmp = ACE_reinterpret_cast (T**,this->buffer_); + for (CORBA::ULong i = ol; i < nl; ++i) + CORBA::release (tmp[i]); +} + #endif /* TAO_SEQUENCE_T_C */ diff --git a/TAO/tao/sequence_T.i b/TAO/tao/sequence_T.i index 9fd2439490d..1ca5d8a57d7 100644 --- a/TAO/tao/sequence_T.i +++ b/TAO/tao/sequence_T.i @@ -123,6 +123,8 @@ TAO_Object_Manager<T>::TAO_Object_Manager(T** ptr, CORBA::Boolean release) : ptr_ (ptr), release_ (release) { + if (this->release_) + T::_duplicate (*this->ptr_); } template <class T> ACE_INLINE @@ -137,81 +139,58 @@ TAO_Object_Manager<T>::operator T* &() // cast return *this->ptr_; } -template <class T> ACE_INLINE const T* -TAO_Object_Manager<T>::in (void) const -{ - return *this->ptr_; -} - -template <class T> ACE_INLINE T*& -TAO_Object_Manager<T>::inout (void) -{ - return *this->ptr_; -} - // ************************************************************* -// class TAO_Unbounded_Managed_Sequence +// class TAO_Unbounded_Object_Sequence // ************************************************************* -template <class T, class Manager> ACE_INLINE void -TAO_Unbounded_Managed_Sequence<T,Manager>::freebuf (T* *seq) -{ - delete []seq; -} - //default constructor -template <class T, class Manager> ACE_INLINE -TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence (void) -{} - -// constructor for unbounded seq -template <class T, class Manager> ACE_INLINE -TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence -(CORBA::ULong maximum) - : TAO_Unbounded_Base_Sequence (maximum, TAO_Unbounded_Managed_Sequence<T,Manager>::allocbuf (max)) +template <class T> ACE_INLINE +TAO_Unbounded_Object_Sequence<T>::TAO_Unbounded_Object_Sequence (void) { } -// constructor from data buffer -template <class T, class Manager> ACE_INLINE -TAO_Unbounded_Managed_Sequence<T,Manager>::TAO_Unbounded_Managed_Sequence -(CORBA::ULong max, CORBA::ULong length, T* *value, CORBA::Boolean release) - : TAO_Unbounded_Base_Sequence (max, length, value, release) +template <class T> ACE_INLINE +TAO_Unbounded_Object_Sequence<T>:: +TAO_Unbounded_Object_Sequence (CORBA::ULong maximum, + CORBA::ULong length, + T* *value, + CORBA::Boolean release) + : TAO_Unbounded_Base_Sequence (maximum, length, value, release) { } -template <class T, class Manager> ACE_INLINE Manager -TAO_Unbounded_Managed_Sequence<T,Manager>::operator[] (CORBA::ULong index) const +template <class T> ACE_INLINE TAO_Object_Manager<T> +TAO_Unbounded_Object_Sequence<T>::operator[] (CORBA::ULong index) const { ACE_ASSERT (index < this->maximum_); - T* tmp = ACE_reinterpret_cast (T*, this->buffer_); + T** tmp = ACE_reinterpret_cast (T**, this->buffer_); return Manager (tmp + index, this->release_); } // ************************************************************* -// class TAO_Bounded_Managed_Sequence +// class TAO_Bounded_Object_Sequence // ************************************************************* -template <class T, class Manager, CORBA::ULong MAX> ACE_INLINE void -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::freebuf (T* *seq) +template <class T, CORBA::ULong MAX> ACE_INLINE void +TAO_Bounded_Object_Sequence<T,MAX>::freebuf (T* *seq) { delete []seq; } -template <class T, class Manager, CORBA::ULong MAX> ACE_INLINE -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::TAO_Bounded_Managed_Sequence (void) +template <class T, CORBA::ULong MAX> ACE_INLINE +TAO_Bounded_Object_Sequence<T,MAX>::TAO_Bounded_Object_Sequence (void) {} // constructor from data buffer -template <class T, class Manager, CORBA::ULong MAX> ACE_INLINE -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::TAO_Bounded_Managed_Sequence +template <class T, CORBA::ULong MAX> ACE_INLINE +TAO_Bounded_Object_Sequence<T,MAX>::TAO_Bounded_Object_Sequence (CORBA::ULong length, T* *value, CORBA::Boolean release) : TAO_Bounded_Base_Sequence (MAX, length, value, release) { } -template <class T, class Manager, CORBA::ULong MAX> ACE_INLINE Manager -TAO_Bounded_Managed_Sequence<T,Manager,MAX>::operator[] (CORBA::ULong index) const +template <class T, CORBA::ULong MAX> ACE_INLINE TAO_Object_Manager<T> +TAO_Bounded_Object_Sequence<T,MAX>::operator[] (CORBA::ULong index) const { ACE_ASSERT (index < this->maximum_); T* tmp = ACE_reinterpret_cast (T*, this->buffer_); diff --git a/TAO/tests/Cubit/TAO/MT_Cubit/server.cpp b/TAO/tests/Cubit/TAO/MT_Cubit/server.cpp index fa2e4687412..d21f6c81194 100644 --- a/TAO/tests/Cubit/TAO/MT_Cubit/server.cpp +++ b/TAO/tests/Cubit/TAO/MT_Cubit/server.cpp @@ -130,14 +130,18 @@ Cubit_Task::create_servants () "implementation object&d\n", i), 2); - CORBA::OctetSeq obj_key; - - obj_key.buffer = (CORBA::Octet *) obj_str; - obj_key.length = obj_key.maximum = ACE_OS::strlen (obj_str); + TAO_opaque obj_key (ACE_OS::strlen (obj_str)); + for (CORBA::ULong i = 0; + i < obj_key.maximum (); + ++i) + { + obj_key[i] = obj_str[i]; + } + obj_key.length (obj_key.maximum ()); CORBA::Object_ptr obj = 0; - if (oa_ptr_->find (obj_key, obj) == -1) + if (this->oa_ptr_->find (obj_key, obj) == -1) ACE_ERROR_RETURN ((LM_ERROR, " (%P|%t) Unable to locate object with key '%s', %p\n", key), |