summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-01-19 05:00:15 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-01-19 05:00:15 +0000
commit0ac6498ccbdf9c8c24280dcb16dc3f29fbef1349 (patch)
treea7ee6f9e16b042ea22662d2763da900ed02085ef
parentddf1a9c7349deed0adde78dce5307762a31952d3 (diff)
downloadATCD-0ac6498ccbdf9c8c24280dcb16dc3f29fbef1349.tar.gz
ChangeLogTag:Sun Jan 18 21:33:21 1998 <coryan@MILONGA>
-rw-r--r--TAO/ChangeLog-98c30
-rw-r--r--TAO/TAO_IDL/be/be_helper.cpp47
-rw-r--r--TAO/TAO_IDL/be/be_visitor_sequence.cpp42
-rw-r--r--TAO/TAO_IDL/be_include/be_helper.h41
-rw-r--r--TAO/orbsvcs/Event_Service/CORBA_Utils_T.cpp2
-rw-r--r--TAO/tao/sequence.cpp198
-rw-r--r--TAO/tao/sequence.h189
-rw-r--r--TAO/tao/sequence.i89
-rw-r--r--TAO/tao/sequence_T.cpp268
-rw-r--r--TAO/tao/sequence_T.i70
-rw-r--r--TAO/tests/Param_Test/tests.cpp104
11 files changed, 757 insertions, 323 deletions
diff --git a/TAO/ChangeLog-98c b/TAO/ChangeLog-98c
index 5a7afdd80a8..5303fae7401 100644
--- a/TAO/ChangeLog-98c
+++ b/TAO/ChangeLog-98c
@@ -1,3 +1,33 @@
+Sun Jan 18 21:33:21 1998 <coryan@MILONGA>
+
+ * tao/sequence.h:
+ * tao/sequence.i:
+ * tao/sequence.cpp:
+ * tao/sequence_T.h:
+ * tao/sequence_T.i:
+ * tao/sequence_T.cpp:
+ Added new class for sequences of strings, the approach based on
+ templates was not worth it.
+ Also fixed a number of bugs in the unbounded object sequences.
+ The following items are in the TODO list:
+ + Bounded sequences of objects
+ + Bounded sequences of strings.
+
+ * TAO_IDL/be_include/be_helper.h:
+ * TAO_IDL/be/be_helper.cpp:
+ Addded small manipulators to indent and unindent an output
+ stream.
+
+ * TAO_IDL/be/be_visitor_sequence.cpp:
+ Synch up with new classes for string and objects.
+
+ * tests/Param_Test/tests.cpp:
+ Fixed some problems with the test for sequences of variable
+ sized structures.
+
+ * orbsvcs/Event_Service/CORBA_Utils_T.cpp:
+ Fixed unsigned/signed comparison.
+
Sun Jan 18 18:30:16 1998 Nanbor Wang <nanbor@cs.wustl.edu>
* TAO/tests/Cubit/TAO/MT_Cubit/*.{dsp.MAK}:
diff --git a/TAO/TAO_IDL/be/be_helper.cpp b/TAO/TAO_IDL/be/be_helper.cpp
index 7c72dedfb97..5281afdee8d 100644
--- a/TAO/TAO_IDL/be/be_helper.cpp
+++ b/TAO/TAO_IDL/be/be_helper.cpp
@@ -32,6 +32,22 @@ TAO_NL::TAO_NL (void)
{
}
+TAO_INDENT::TAO_INDENT (int do_now)
+ : do_now_ (do_now)
+{
+}
+
+TAO_UNINDENT::TAO_UNINDENT (int do_now)
+ : do_now_ (do_now)
+{
+}
+
+const TAO_NL be_nl;
+const TAO_INDENT be_idt;
+const TAO_INDENT be_idt_nl (1);
+const TAO_UNINDENT be_uidt;
+const TAO_UNINDENT be_uidt_nl (1);
+
// methods of the TAO_OutStream class
TAO_OutStream::TAO_OutStream (void)
@@ -135,6 +151,14 @@ TAO_OutStream::indent (void)
return 0;
}
+int
+TAO_OutStream::nl (void)
+{
+ ACE_OS::fprintf (this->fp_, "\n");
+ this->indent ();
+ return 0;
+}
+
// macro generation
int
TAO_OutStream::gen_ifdef_macro (const char *flatname, const char *suffix)
@@ -213,17 +237,32 @@ TAO_OutStream::operator<< (const long num)
}
TAO_OutStream &
-TAO_OutStream::operator<< (const TAO_NL nl)
+TAO_OutStream::operator<< (const TAO_NL&)
{
- // Macro to avoid "warning: unused parameter" type warning.
- ACE_UNUSED_ARG (nl);
-
ACE_OS::fprintf (this->fp_ , "\n");
this->indent ();
return *this;
}
TAO_OutStream &
+TAO_OutStream::operator<< (const TAO_INDENT& i)
+{
+ this->incr_indent (0);
+ if (i.do_now_)
+ this->nl ();
+ return *this;
+}
+
+TAO_OutStream &
+TAO_OutStream::operator<< (const TAO_UNINDENT& i)
+{
+ this->decr_indent (0);
+ if (i.do_now_)
+ this->nl ();
+ return *this;
+}
+
+TAO_OutStream &
TAO_OutStream::operator<< (Identifier *id)
{
return this->print (id);
diff --git a/TAO/TAO_IDL/be/be_visitor_sequence.cpp b/TAO/TAO_IDL/be/be_visitor_sequence.cpp
index 286ac06b3f8..aee6b4f9f86 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;
@@ -190,7 +206,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 ();
}
@@ -217,10 +233,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;
}
@@ -229,22 +241,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/TAO_IDL/be_include/be_helper.h b/TAO/TAO_IDL/be_include/be_helper.h
index 32af2898748..37bf67d7ca7 100644
--- a/TAO/TAO_IDL/be_include/be_helper.h
+++ b/TAO/TAO_IDL/be_include/be_helper.h
@@ -27,6 +27,40 @@ public:
TAO_NL (void);
};
+struct TAO_INDENT
+{
+ // = TITLE
+ // Operates like a manipulator, increasing the indentation level.
+ //
+ // = DESCRIPTION
+ // Increase the indentation level, if the "do_now" parameter is
+ // not zero then the <indent> method is called on the stream.
+ //
+ TAO_INDENT (int do_now = 0);
+
+ const int do_now_;
+};
+
+struct TAO_UNINDENT
+{
+ // = TITLE
+ // Operates like a manipulator, decreasing the indentation level.
+ //
+ // = DESCRIPTION
+ // Increase the indentation level, if the "do_now" parameter is
+ // not zero then the <indent> method is called on the stream.
+ //
+ TAO_UNINDENT (int do_now = 0);
+
+ const int do_now_;
+};
+
+extern const TAO_NL be_nl;
+extern const TAO_INDENT be_idt;
+extern const TAO_INDENT be_idt_nl;
+extern const TAO_UNINDENT be_uidt;
+extern const TAO_UNINDENT be_uidt_nl;
+
class TAO_OutStream
{
// =TITLE
@@ -99,7 +133,12 @@ public:
TAO_OutStream &operator<< (const long num);
// output the integer and return a reference to ourselves
- TAO_OutStream &operator<< (const TAO_NL nl);
+ // = MANIPULATORS
+
+ TAO_OutStream &operator<< (const TAO_NL& nl);
+ TAO_OutStream &operator<< (const TAO_INDENT& i);
+ TAO_OutStream &operator<< (const TAO_UNINDENT& i);
+
// The following will be provided by specialized classes
TAO_OutStream &operator<< (Identifier *id);
diff --git a/TAO/orbsvcs/Event_Service/CORBA_Utils_T.cpp b/TAO/orbsvcs/Event_Service/CORBA_Utils_T.cpp
index f603421eaaa..cb685721d3b 100644
--- a/TAO/orbsvcs/Event_Service/CORBA_Utils_T.cpp
+++ b/TAO/orbsvcs/Event_Service/CORBA_Utils_T.cpp
@@ -120,7 +120,7 @@ ACE_CORBA_Sequence<TYPE>::length (CORBA::ULong len)
// Allocate the space that we need.
TYPE* tmp = this->new_array (len);
// Copy over the old sequence.
- for (int i = 0; i < maximum_; ++i)
+ for (CORBA::ULong i = 0; i < maximum_; ++i)
{
tmp[i] = buffer_[i];
}
diff --git a/TAO/tao/sequence.cpp b/TAO/tao/sequence.cpp
index ab4323c1896..746ec881c06 100644
--- a/TAO/tao/sequence.cpp
+++ b/TAO/tao/sequence.cpp
@@ -16,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&
@@ -40,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 1cb428d9900..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,45 +211,138 @@ 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
-
- // in, inout, out, _retn
- const char *in (void) const;
- // returns the underlying string
-
- char *&inout (void);
- // returns a reference to the underlying string for in arguments
-
- char *&out (void);
- // used for out arguments
-
- char *_retn (void);
- // gives up ownership, used for return types.
-
private:
- char **ptr_;
+ char* *ptr_;
// address of string element from the parent's buffer
CORBA::Boolean release_;
- // based on parent's release flag
+ // control memory managment semantics.
};
+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;
+
+ // =operations for the Unbounded_ObjectSequence
+
+ 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
+ // deep­copy to create a new structure.
+ //
+ // The assignment operator deep­copies 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);
+};
+
+
#if defined (__ACE_INLINE__)
#include "tao/sequence.i"
#endif /* __ACE_INLINE__ */
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 201bcd5f371..38e31742c48 100644
--- a/TAO/tao/sequence_T.cpp
+++ b/TAO/tao/sequence_T.cpp
@@ -148,14 +148,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_ = T::_duplicate (*rhs.ptr_);
- this->release_ = _tao_mng_type.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;
@@ -177,89 +177,133 @@ 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++)
- tmp [i] = T::_duplicate (tmp2 [i]);
+ CORBA::ULong i = 0;
+ for (; i < seq.length_; ++i)
+ tmp1 [i] = T::_duplicate (tmp2 [i]);
+
+ for (; i < seq.maximum_; ++i)
+ tmp1 [i] = T::_nil ();
+
+ this->release_ = 1;
+}
+
+template<class T>
+TAO_Unbounded_Object_Sequence<T>::~TAO_Unbounded_Object_Sequence (void)
+{
+ this->_deallocate_buffer ();
}
// 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++)
- tmp [i] = T::_duplicate (tmp2 [i]);
+ CORBA::ULong i=0;
+ for (; i < seq.length_; ++i)
+ tmp1 [i] = T::_duplicate (tmp2 [i]);
+ for (; i < seq.maximum_; ++i)
+ tmp1 [i] = T::_nil ();
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]);
@@ -269,42 +313,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_);
@@ -313,46 +378,36 @@ 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++)
- tmp [i] = T::_duplicate (tmp2 [i]);
+ tmp1 [i] = T::_duplicate (tmp2 [i]);
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]);
@@ -361,16 +416,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;
@@ -381,4 +434,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 e2ae782032f..25d505f72b0 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** buffer, CORBA::Boolean release)
: ptr_ (buffer),
release_ (release)
{
+ if (this->release_)
+ T::_duplicate (*this->ptr_);
}
template <class T> ACE_INLINE
@@ -137,81 +139,59 @@ 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_Unbounded_Object_Sequence<T>::Manager
+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_Bounded_Object_Sequence<T,MAX>::Manager
+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/Param_Test/tests.cpp b/TAO/tests/Param_Test/tests.cpp
index 1285f8230f0..dd09aa3f4f9 100644
--- a/TAO/tests/Param_Test/tests.cpp
+++ b/TAO/tests/Param_Test/tests.cpp
@@ -1,5 +1,6 @@
// $Id$
+
// ============================================================================
//
// = LIBRARY
@@ -616,7 +617,7 @@ Test_String_Sequence::print_values (void)
"Element #%d\n"
"in : %s\n",
i,
- (this->in_[i].in ()? (char *)this->in_[i].in ():"<nul>")));
+ this->in_[i]? (const char *)this->in_[i]:"<nul>"));
}
if (!this->in_.ptr ())
ACE_DEBUG ((LM_DEBUG, "\nin sequence is NUL\n"));
@@ -627,7 +628,7 @@ Test_String_Sequence::print_values (void)
"Element #%d\n"
"in : %s\n",
i,
- (this->inout_[i].in ()? (char *)this->inout_[i].in ():"<nul>")));
+ (this->inout_[i]? (const char *)this->inout_[i]:"<nul>")));
}
if (!this->inout_.ptr ())
ACE_DEBUG ((LM_DEBUG, "\ninout sequence is NUL\n"));
@@ -638,7 +639,7 @@ Test_String_Sequence::print_values (void)
"Element #%d\n"
"in : %s\n",
i,
- (this->out_[i].in ()? (char *)this->out_[i].in ():"<nul>")));
+ (this->out_[i]? (const char *)this->out_[i]:"<nul>")));
}
if (!this->out_.ptr ())
ACE_DEBUG ((LM_DEBUG, "\nout sequence is NUL\n"));
@@ -649,7 +650,7 @@ Test_String_Sequence::print_values (void)
"Element #%d\n"
"in : %s\n",
i,
- (this->ret_[i].in ()? (char *)this->ret_[i].in ():"<nul>")));
+ (this->ret_[i]? (const char *)this->ret_[i]:"<nul>")));
}
if (!this->ret_.ptr ())
ACE_DEBUG ((LM_DEBUG, "\nin sequence is NUL\n"));
@@ -825,7 +826,7 @@ Test_Var_Struct::print_values (void)
"Element #%d\n"
"in.seq : %s\n",
i,
- (this->in_.seq[i].in ()? (char *)this->in_.seq[i].in ():"<nul>")));
+ (this->in_.seq[i]? (const char *)this->in_.seq[i]:"<nul>")));
}
ACE_DEBUG ((LM_DEBUG, "\n*=*=*=*=*=*=*=*=*=*=\n"));
for (i=0; this->inout_.ptr () && (i < this->inout_->seq.length ()); i++)
@@ -834,7 +835,7 @@ Test_Var_Struct::print_values (void)
"Element #%d\n"
"inout : %s\n",
i,
- (this->inout_->seq[i].in ()? (char *)this->inout_->seq[i].in ():"<nul>")));
+ (this->inout_->seq[i]? (const char *)this->inout_->seq[i]:"<nul>")));
}
if (!this->inout_.ptr ())
ACE_DEBUG ((LM_DEBUG, "\ninout struct does not exist\n"));
@@ -845,7 +846,7 @@ Test_Var_Struct::print_values (void)
"Element #%d\n"
"in : %s\n",
i,
- (this->out_->seq[i].in ()? (char *)this->out_->seq[i].in ():"<nul>")));
+ (this->out_->seq[i]? (const char *)this->out_->seq[i]:"<nul>")));
}
if (!this->out_.ptr ())
ACE_DEBUG ((LM_DEBUG, "\nout struct is NUL\n"));
@@ -856,7 +857,7 @@ Test_Var_Struct::print_values (void)
"Element #%d\n"
"in : %s\n",
i,
- (this->ret_->seq[i].in ()? (char *)this->ret_->seq[i].in ():"<nul>")));
+ (this->ret_->seq[i]? (const char *)this->ret_->seq[i]:"<nul>")));
}
if (!this->ret_.ptr ())
ACE_DEBUG ((LM_DEBUG, "\nret struct is NUL\n"));
@@ -1005,13 +1006,13 @@ Test_Nested_Struct::print_values (void)
"out (len = %d): %s\n"
"ret (len = %d): %s\n",
this->in_.vs.seq.length (),
- (this->in_.vs.seq.length ()? (char *)this->in_.vs.seq[i]:"<nul>"),
+ (this->in_.vs.seq.length ()? (const char *)this->in_.vs.seq[i]:"<nul>"),
this->inout_->vs.seq.length (),
- (this->inout_->vs.seq.length ()? (char *)this->inout_->vs.seq[i]:"<nul>"),
+ (this->inout_->vs.seq.length ()? (const char *)this->inout_->vs.seq[i]:"<nul>"),
this->out_->vs.seq.length (),
- (this->out_->vs.seq.length ()? (char *)this->out_->vs.seq[i]:"<nul>"),
+ (this->out_->vs.seq.length ()? (const char *)this->out_->vs.seq[i]:"<nul>"),
this->ret_->vs.seq.length (),
- (this->ret_->vs.seq.length ()? (char *)this->ret_->vs.seq[i]:"<nul>")));
+ (this->ret_->vs.seq.length ()? (const char *)this->ret_->vs.seq[i]:"<nul>")));
}
}
@@ -1053,14 +1054,19 @@ Test_Struct_Sequence::init_parameters (Param_Test_ptr objref,
CORBA::ULong len = (CORBA::ULong) (gen->gen_long () % 10) + 1;
// set the length of the sequence
- this->in_.vs.seq.length (len);
+ this->in_.length (len);
// now set each individual element
- for (CORBA::ULong i=0; i < this->in_.vs.seq.length (); i++)
+ for (CORBA::ULong i=0; i < this->in_.length (); i++)
{
// generate some arbitrary string to be filled into the ith location in
// the sequence
- char *str = gen->gen_string ();
- this->in_.vs.seq[i] = str;
+ this->in_[i].dummy1 = gen->gen_string ();
+ this->in_[i].dummy2 = gen->gen_string ();
+
+ CORBA::ULong len2 = (CORBA::ULong) (gen->gen_long () % 3) + 1;
+ this->in_[i].seq.length (len2);
+ for (CORBA::ULong j = 0; j < this->in_[i].seq.length (); j++)
+ this->in_[i].seq[j] = gen->gen_string ();
}
return 0;
}
@@ -1079,7 +1085,7 @@ Test_Struct_Sequence::run_sii_test (Param_Test_ptr objref,
CORBA::Environment &env)
{
Param_Test::StructSeq_out out (this->out_.out ());
- this->ret_ = objref->test_Struct_Sequence (this->in_,
+ this->ret_ = objref->test_struct_sequence (this->in_,
this->inout_.inout (),
out,
env);
@@ -1091,9 +1097,9 @@ Test_Struct_Sequence::add_args (CORBA::NVList_ptr &param_list,
CORBA::NVList_ptr &retval,
CORBA::Environment &env)
{
- CORBA::Any in_arg (Param_Test::_tc_Struct_Sequence, (void *) &this->in_, 0);
- CORBA::Any inout_arg (Param_Test::_tc_Struct_Sequence, &this->inout_.inout (), 0);
- CORBA::Any out_arg (Param_Test::_tc_Struct_Sequence, this->out_.out (), 0);
+ CORBA::Any in_arg (Param_Test::_tc_StructSeq, (void *) &this->in_, 0);
+ CORBA::Any inout_arg (Param_Test::_tc_StructSeq, &this->inout_.inout (), 0);
+ CORBA::Any out_arg (Param_Test::_tc_StructSeq, this->out_.out (), 0);
// add parameters
(void)param_list->add_value ("s1", in_arg, CORBA::ARG_IN, env);
@@ -1101,7 +1107,7 @@ Test_Struct_Sequence::add_args (CORBA::NVList_ptr &param_list,
(void)param_list->add_value ("s3", out_arg, CORBA::ARG_OUT, env);
// add return value
- (void)retval->item (0, env)->value ()->replace (Param_Test::_tc_Struct_Sequence,
+ (void)retval->item (0, env)->value ()->replace (Param_Test::_tc_StructSeq,
&this->ret_,
0, // does not own
env);
@@ -1129,26 +1135,54 @@ Test_Struct_Sequence::check_validity (CORBA::Request_ptr req)
return this->check_validity ();
}
+static void print_var_struct (const Param_Test::Var_Struct& vs)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ " dummy1 = <%s>\n"
+ " dummy2 = <%s>\n"
+ " seq length: %d\n",
+ vs.dummy1.in ()?(const char*)vs.dummy1.in ():"",
+ vs.dummy2.in ()?(const char*)vs.dummy2.in ():"",
+ vs.seq.length ()));
+ for (CORBA::ULong i = 0; i < vs.seq.length (); ++i)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ " seq[%d] = <%s>\n",
+ i, (const char*)vs.seq[i]));
+ }
+}
+
void
Test_Struct_Sequence::print_values (void)
{
- for (CORBA::ULong i=0; i < this->in_.vs.seq.length (); i++)
+ CORBA::ULong i;
+ for (i = 0; i < this->in_.length (); i++)
{
ACE_DEBUG ((LM_DEBUG,
"\n*=*=*=*=*=*=*=*=*=*=\n"
- "Element # %d\n"
- "in (len = %d): %s\n"
- "inout (len = %d): %s\n"
- "out (len = %d): %s\n"
- "ret (len = %d): %s\n",
- this->in_.vs.seq.length (),
- (this->in_.vs.seq.length ()? (char *)this->in_.vs.seq[i]:"<nul>"),
- this->inout_->vs.seq.length (),
- (this->inout_->vs.seq.length ()? (char *)this->inout_->vs.seq[i]:"<nul>"),
- this->out_->vs.seq.length (),
- (this->out_->vs.seq.length ()? (char *)this->out_->vs.seq[i]:"<nul>"),
- this->ret_->vs.seq.length (),
- (this->ret_->vs.seq.length ()? (char *)this->ret_->vs.seq[i]:"<nul>")));
+ "IN Element # %d\n"));
+ print_var_struct (this->in_[i]);
+ }
+ for (i = 0; i < this->inout_->length (); i++)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "\n*=*=*=*=*=*=*=*=*=*=\n"
+ "INOUT Element # %d\n"));
+ print_var_struct (this->inout_[i]);
+ }
+ for (i = 0; i < this->out_->length (); i++)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "\n*=*=*=*=*=*=*=*=*=*=\n"
+ "OUT Element # %d\n"));
+ print_var_struct (this->out_[i]);
+ }
+ for (i = 0; i < this->ret_->length (); i++)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "\n*=*=*=*=*=*=*=*=*=*=\n"
+ "RET Element # %d\n"));
+ print_var_struct (this->ret_[i]);
}
}