From b50cd074a817c735a71af7283ba33db3b1d1973f Mon Sep 17 00:00:00 2001 From: gokhale Date: Wed, 15 Apr 1998 21:54:11 +0000 Subject: *** empty log message *** --- TAO/ChangeLog-98c | 47 +++- TAO/tao/Any.cpp | 1 + TAO/tao/CDR.cpp | 22 ++ TAO/tao/CDR.h | 37 +++ TAO/tao/CDR.i | 127 +++++++++ TAO/tao/Exception.cpp | 61 ++++- TAO/tao/Exception.h | 45 +++- TAO/tao/Exception.i | 16 ++ TAO/tao/GIOP.cpp | 10 +- TAO/tao/IIOP_Object.cpp | 1 - TAO/tao/Makefile | 1 + TAO/tao/Marshal.h | 84 ++++++ TAO/tao/ORB.h | 4 +- TAO/tao/Typecode.cpp | 4 +- TAO/tao/Typecode.h | 41 ++- TAO/tao/append.cpp | 705 ++++++++++++++++++++++++++++++++++++++++++++++++ TAO/tao/corba.h | 3 + TAO/tao/decode.cpp | 5 +- TAO/tao/encode.cpp | 71 +---- TAO/tao/skip.cpp | 10 +- 20 files changed, 1181 insertions(+), 114 deletions(-) create mode 100644 TAO/tao/append.cpp diff --git a/TAO/ChangeLog-98c b/TAO/ChangeLog-98c index 056fe554b2d..860ba8e1e77 100644 --- a/TAO/ChangeLog-98c +++ b/TAO/ChangeLog-98c @@ -1,3 +1,48 @@ +Wed Apr 15 15:59:58 1998 Aniruddha Gokhale + + * TAO/tao/append.cpp: Added a bunch of methods that take a CDR + stream and append it to another CDR stream while maintaining the + alignment. These functions use exactly the same logic as that used + by the encode, skip, decode, deep_free, and deep_copy methods. + + * TAO/tao/any.cpp: When we reset the contents, we set value_ to 0 + + * TAO/tao/CDR.{h, i, cpp}: Added a constructor to the + TAO_OutputCDR and TAO_InputCDR to take an ACE_Message_Block as + input. In addition, added the "append" methods that append one CDR + to other while maintaining the alignment. + + * TAO/tao/Exception.{h, i, cpp}: Added the definition and + implementation of the CORBA::ExceptionList class according to the + CORBA v2.2 (Feb 98). This required a few changes in the + Exception.cpp file while initializing the list of system + exceptions. + + * TAO/tao/{GIOP, IIOP_Object}.cpp: Changes required due the new + definition of ExceptionList + + * TAO/tao/Marshal.h: Added the append methods on all classes. + + * TAO/tao/ORB.h: Chnaged the definition of ExceptionList from + typedef to TAO_Unbounded_Object_Sequence to using + the new defintion. + + * TAO/tao/Typecode.{h, cpp}: Moved the defintions of Bounds and + BadKind inside the TypeCode class. This is where it belongs. + + * TAO/tao/decode.cpp: In Any::decode, we set the value_ data + member of Any to a duplicated ACE_Message_Block. + + * TAO/tao/encode.cpp: Changed the implementation of Any::encode + such that if the Any owns the data, then the value_ which is an + ACE_Message_Block that holds a CDR stream gets appended to the + destination CDR. Otherwise, the value is literally encoded into + the destination CDR. + + * TAO/tao/skip.cpp: Added WString::skip. In addition, we had + forgotten to pass the address of the discriminant_val to the + decoder inside the Union::skip function. + Wed Apr 15 12:19:36 1998 Nanbor Wang * tao/deep_copy.cpp (deep_copy): We need a return if no error was @@ -5,7 +50,7 @@ Wed Apr 15 12:19:36 1998 Nanbor Wang Wed Apr 15 09:28:16 1998 Carlos O'Ryan - * tao/Stub.h: + * tao/Stub.h: A field was declared , this field is needed to initialize a Sequence that requires a parameter. The careful reader will notice diff --git a/TAO/tao/Any.cpp b/TAO/tao/Any.cpp index b9b35548fbe..eca416a0bc1 100644 --- a/TAO/tao/Any.cpp +++ b/TAO/tao/Any.cpp @@ -196,6 +196,7 @@ CORBA_Any::~CORBA_Any (void) { // decrement the refcount on the Message_Block we hold ACE_Message_Block::release ((ACE_Message_Block *) this->value_); + this->value_ = 0; } if (this->type_) diff --git a/TAO/tao/CDR.cpp b/TAO/tao/CDR.cpp index 2fe36da874d..9d682b195e9 100644 --- a/TAO/tao/CDR.cpp +++ b/TAO/tao/CDR.cpp @@ -170,6 +170,18 @@ TAO_OutputCDR::TAO_OutputCDR (char *data, size_t size, CDR::mb_align (this->start_); } +TAO_OutputCDR::TAO_OutputCDR (ACE_Message_Block *data, + int byte_order, + TAO_Marshal_Factory *factory) + : factory_ (factory), + do_byte_swap_ (byte_order != TAO_ENCAP_BYTE_ORDER), + good_bit_ (1) +{ + this->start_ = ACE_Message_Block::duplicate (data); + // We cannot trust the buffer to be properly aligned + CDR::mb_align (this->start_); +} + TAO_OutputCDR::~TAO_OutputCDR (void) { ACE_Message_Block::release (this->start_); @@ -468,6 +480,16 @@ TAO_InputCDR::TAO_InputCDR (const char *buf, size_t bufsiz, this->start_->wr_ptr (bufsiz); } +TAO_InputCDR::TAO_InputCDR (ACE_Message_Block *data, + int byte_order, + TAO_Marshal_Factory *factory) + : factory_ (factory), + do_byte_swap_ (byte_order != TAO_ENCAP_BYTE_ORDER), + good_bit_ (1) +{ + this->start_ = ACE_Message_Block::duplicate (data); +} + TAO_InputCDR::TAO_InputCDR (const TAO_InputCDR& rhs, size_t size, CORBA::Long offset) diff --git a/TAO/tao/CDR.h b/TAO/tao/CDR.h index 5710ec02cd6..fdef84720a3 100644 --- a/TAO/tao/CDR.h +++ b/TAO/tao/CDR.h @@ -153,6 +153,13 @@ public: // Build a CDR stream with an initial buffer, it will *not* remove // , since it did not allocated it. + TAO_OutputCDR (ACE_Message_Block *data, + int byte_order = TAO_ENCAP_BYTE_ORDER, + TAO_Marshal_Factory *f = + TAO_Marshal::DEFAULT_MARSHAL_FACTORY); + // Build a CDR stream with an initial Message_Block chain, it will *not* + // remove , since it did not allocate it. + ~TAO_OutputCDR (void); // destructor @@ -203,6 +210,30 @@ public: CORBA_Boolean write_longdouble_array (const CORBA::LongDouble* x, CORBA::ULong length); + // = We have one method per basic IDL type.... + // They return CORBA::B_FALSE on failure and CORBA::B_TRUE on success. + CORBA_Boolean append_boolean (TAO_InputCDR &); + CORBA_Boolean append_char (TAO_InputCDR &); + CORBA_Boolean append_wchar (TAO_InputCDR &); + CORBA_Boolean append_octet (TAO_InputCDR &); + CORBA_Boolean append_short (TAO_InputCDR &); + CORBA_Boolean append_ushort (TAO_InputCDR &); + CORBA_Boolean append_long (TAO_InputCDR &); + CORBA_Boolean append_ulong (TAO_InputCDR &); + CORBA_Boolean append_longlong (TAO_InputCDR &); + CORBA_Boolean append_ulonglong (TAO_InputCDR &); + CORBA_Boolean append_float (TAO_InputCDR &); + CORBA_Boolean append_double (TAO_InputCDR &); + CORBA_Boolean append_longdouble (TAO_InputCDR &); + CORBA_Boolean append_wstring (TAO_InputCDR &); + CORBA_Boolean append_string (TAO_InputCDR &); + + CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + CORBA::Environment &env); + // Append the contents of the CDR stream based on information + // described by ; returning any errors in . + // @@ TODO: do we want a special method to write an array of // strings and wstrings? @@ -333,6 +364,12 @@ public: // exercised wrt alignment, because this contructor will *not* work // if the buffer is unproperly aligned. + TAO_InputCDR (ACE_Message_Block *data, + int byte_order = TAO_ENCAP_BYTE_ORDER, + TAO_Marshal_Factory *f = + TAO_Marshal::DEFAULT_MARSHAL_FACTORY); + // Create an input stream from an ACE_Message_Block + TAO_InputCDR (const TAO_InputCDR& rhs); TAO_InputCDR& operator= (const TAO_InputCDR& rhs); // Make a copy of the current stream state, but does not copy the diff --git a/TAO/tao/CDR.i b/TAO/tao/CDR.i index eccd836baca..6d794e74441 100644 --- a/TAO/tao/CDR.i +++ b/TAO/tao/CDR.i @@ -767,3 +767,130 @@ operator>> (TAO_InputCDR& cdr, CORBA::Char &x) return cdr; } #endif /* 0 */ + +// *************************************************************************** +// We must define these methods here because they use the "read_*" inlined +// methods of the TAO_InputCDR class +// *************************************************************************** + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_boolean (TAO_InputCDR &stream) +{ + CORBA::Boolean x; + return (stream.read_boolean (x) ? this->write_boolean (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_char (TAO_InputCDR &stream) +{ + CORBA::Char x; + return (stream.read_char (x) ? this->write_char (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_wchar (TAO_InputCDR &stream) +{ + CORBA::WChar x; + return (stream.read_wchar (x) ? this->write_wchar (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_octet (TAO_InputCDR &stream) +{ + CORBA::Octet x; + return (stream.read_octet (x) ? this->write_octet (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_short (TAO_InputCDR &stream) +{ + CORBA::Short x; + return (stream.read_short (x) ? this->write_short (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_ushort (TAO_InputCDR &stream) +{ + CORBA::UShort x; + return (stream.read_ushort (x) ? this->write_ushort (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_long (TAO_InputCDR &stream) +{ + CORBA::Long x; + return (stream.read_long (x) ? this->write_long (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_ulong (TAO_InputCDR &stream) +{ + CORBA::ULong x; + return (stream.read_ulong (x) ? this->write_ulong (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_longlong (TAO_InputCDR &stream) +{ + CORBA::LongLong x; + return (stream.read_longlong (x) ? this->write_longlong (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_ulonglong (TAO_InputCDR &stream) +{ + CORBA::ULongLong x; + return (stream.read_ulonglong (x) ? this->write_ulonglong (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_float (TAO_InputCDR &stream) +{ + CORBA::Float x; + return (stream.read_float (x) ? this->write_float (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_double (TAO_InputCDR &stream) +{ + CORBA::Double x; + return (stream.read_double (x) ? this->write_double (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_longdouble (TAO_InputCDR &stream) +{ + CORBA::LongDouble x; + return (stream.read_longdouble (x) ? this->write_longdouble (x) : 0); +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_string (TAO_InputCDR &stream) +{ + char *x; + CORBA::Boolean flag = (stream.read_string (x) ? this->write_string (x) : 0); + CORBA::string_free (x); + return flag; +} + +ACE_INLINE CORBA_Boolean +TAO_OutputCDR::append_wstring (TAO_InputCDR &stream) +{ + CORBA::WChar *x; + CORBA::Boolean flag = (stream.read_wstring (x) ? this->write_wstring (x) : 0); + CORBA::wstring_free (x); + return flag; +} + +ACE_INLINE CORBA::TypeCode::traverse_status +TAO_OutputCDR::append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + CORBA::Environment &env) +{ + TAO_Marshal_Object *mobj = + this->factory_->make_marshal_object (tc, env); + + if (env.exception() == 0 && mobj != 0) + return mobj->append (tc, src, this, env); + return CORBA::TypeCode::TRAVERSE_STOP; +} diff --git a/TAO/tao/Exception.cpp b/TAO/tao/Exception.cpp index 161c56c6699..0abae3351f8 100644 --- a/TAO/tao/Exception.cpp +++ b/TAO/tao/Exception.cpp @@ -325,13 +325,14 @@ TAO_Exceptions::make_standard_typecode (CORBA::TypeCode_ptr tcp, // a TypeCode, saving it away in the list of ones that the ORB will // always accept as part of any operation response! - int l = TAO_Exceptions::system_exceptions.length (); - TAO_Exceptions::system_exceptions.length (l + 1); - TAO_Exceptions::sys_exceptions [l] = - new (tcp) CORBA::TypeCode (CORBA::tk_except, - stream.length (), - stream.buffer (), - CORBA::B_FALSE); + CORBA::ULong l = TAO_Exceptions::system_exceptions.count (); + TAO_Exceptions::system_exceptions.add ( + new (tcp) CORBA::TypeCode + (CORBA::tk_except, + stream.length (), + stream.buffer (), + CORBA::B_FALSE) + ); assert (tcp->length_ <= TAO_Exceptions::TC_BUFLEN); return; @@ -388,11 +389,7 @@ TAO_Exceptions::init_standard_exceptions (CORBA::Environment &env) { // Initialize the list of system exceptions, used when // unmarshaling. - TAO_Exceptions::system_exceptions = - CORBA::ExceptionList (TAO_Exceptions::NUM_SYS_EXCEPTIONS, 0, - TAO_Exceptions::sys_exceptions); - // Initialize the typecodes. #define TAO_SYSTEM_EXCEPTION(name) \ if (env.exception () == 0) \ TAO_Exceptions::make_standard_typecode (&tc_std_ ## name, #name, \ @@ -546,3 +543,45 @@ CORBA::Environment::print_exception (const char *info, "(%P|%t) user exception, ID '%s'\n", id)); } + +CORBA_ExceptionList::CORBA_ExceptionList (CORBA::ULong len, + CORBA::TypeCode_ptr *tc_list) +{ + for (CORBA::ULong i=0; i < len; i++) + this->add (tc_list [i]); +} + +void +CORBA_ExceptionList::add (CORBA::TypeCode_ptr tc) +{ + this->tc_list_.enqueue_tail (CORBA::TypeCode::_duplicate (tc)); +} + +void +CORBA_ExceptionList::add_consume (CORBA::TypeCode_ptr tc) +{ + this->tc_list_.enqueue_tail (tc); +} + +CORBA::TypeCode_ptr +CORBA_ExceptionList::item (CORBA::ULong index, + CORBA::Environment &env) +{ + CORBA::TypeCode_ptr *tc; + env.clear (); + if (this->tc_list_.get (tc, index) == -1) + { + env.exception (new CORBA::TypeCode::Bounds); + return 0; + } + else + { + return CORBA::TypeCode::_duplicate (*tc); + } +} +void +CORBA_ExceptionList::remove (CORBA::ULong index, CORBA::Environment &env) +{ + // unimplemented + env.clear (); +} diff --git a/TAO/tao/Exception.h b/TAO/tao/Exception.h index d665ca10f31..0f74b2939f9 100644 --- a/TAO/tao/Exception.h +++ b/TAO/tao/Exception.h @@ -283,11 +283,54 @@ public: // Preallocated tc buffer. }; - static CORBA::TypeCode_ptr sys_exceptions[NUM_SYS_EXCEPTIONS]; + static CORBA::TypeCode_ptr sys_exceptions [NUM_SYS_EXCEPTIONS]; static CORBA::ExceptionList system_exceptions; }; +// ExceptionList definition taken from CORBA v2.2 Feb 1998 +class CORBA_ExceptionList +{ + // =TITLE + // CORBA_ExceptionList + // =DESCRIPTION + // Maintains a list of TypeCodes for Exceptions +public: + + CORBA_ExceptionList (void); + // constructor + + CORBA_ExceptionList (CORBA::ULong len, + CORBA::TypeCode_ptr *tc_list); + // constructor - initialize given a length and an array of TypeCodes + + ~CORBA_ExceptionList (void); + // destructor + + CORBA::ULong count (); + // return the number of elements + + void add (CORBA::TypeCode_ptr tc); + // add a TypeCode to the list + + void add_consume (CORBA::TypeCode_ptr tc); + // add and consume a TypeCode to the list + + CORBA::TypeCode_ptr item (CORBA::ULong index, CORBA::Environment &env); + // return the typecode at index i. Raises the "Bounds" exception + + void remove (CORBA::ULong index, CORBA::Environment &env); + // remove the typecode at index i. Raises the "Bounds" exception + +private: + // not allowed + CORBA_ExceptionList (const CORBA_ExceptionList &); + CORBA_ExceptionList &operator= (const CORBA_ExceptionList &); + + ACE_Unbounded_Queue tc_list_; + // internal list of typecodes +}; + #if defined (__ACE_INLINE__) # include "tao/Exception.i" #endif /* __ACE_INLINE__ */ diff --git a/TAO/tao/Exception.i b/TAO/tao/Exception.i index a629b7b13d2..269a0162138 100644 --- a/TAO/tao/Exception.i +++ b/TAO/tao/Exception.i @@ -43,3 +43,19 @@ CORBA::Exception_ptr CORBA_Environment::exception (void) const { return this->exception_; } + +ACE_INLINE +CORBA_ExceptionList::CORBA_ExceptionList (void) +{ +} + +ACE_INLINE +CORBA_ExceptionList::~CORBA_ExceptionList (void) +{ +} + +ACE_INLINE CORBA::ULong +CORBA_ExceptionList::count (void) +{ + return (CORBA::ULong) this->tc_list_.size (); +} diff --git a/TAO/tao/GIOP.cpp b/TAO/tao/GIOP.cpp index 1187f669275..ef119c34798 100644 --- a/TAO/tao/GIOP.cpp +++ b/TAO/tao/GIOP.cpp @@ -1023,11 +1023,11 @@ TAO_GIOP_Invocation::invoke (CORBA::ExceptionList &exceptions, // fail (next). for (CORBA::ULong i = 0; - i < xlist->length (); + i < xlist->count (); i++) { - CORBA::TypeCode_ptr tcp = (*xlist) [i]; - + CORBA::TypeCode_ptr tcp = xlist->item (i, env); + const char *xid = tcp->id (env); if (env.exception () != 0) @@ -1232,7 +1232,7 @@ TAO_GIOP::start_message (TAO_GIOP::Message_Type type, msg.write_octet (type); // Write a dummy later it is set to the right value... - // @@ TODO Maybe we should store the OutputCDR status in + // @@ TODO Maybe we should store the OutputCDR status in CORBA::ULong size = 0; msg.write_ulong (size); @@ -1242,11 +1242,9 @@ TAO_GIOP::start_message (TAO_GIOP::Message_Type type, #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class TAO_Unbounded_Sequence; template class TAO_Unbounded_Sequence; -template class TAO_Unbounded_Sequence; template class TAO_Unbounded_Object_Sequence; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate TAO_Unbounded_Sequence #pragma instantiate TAO_Unbounded_Sequence -#pragma instantiate TAO_Unbounded_Sequence #pragma instantiate TAO_Unbounded_Object_Sequence #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/tao/IIOP_Object.cpp b/TAO/tao/IIOP_Object.cpp index 700076f6bea..d209ca8a1b6 100644 --- a/TAO/tao/IIOP_Object.cpp +++ b/TAO/tao/IIOP_Object.cpp @@ -492,7 +492,6 @@ IIOP_Object::do_static_call (CORBA::Environment &env, // exception reporting TAO_GIOP_ReplyStatusType status; CORBA::ExceptionList exceptions (info->except_count, - info->except_count, info->excepts); status = call.invoke (exceptions, env); diff --git a/TAO/tao/Makefile b/TAO/tao/Makefile index 1e0bf817d02..8835b01cb9c 100644 --- a/TAO/tao/Makefile +++ b/TAO/tao/Makefile @@ -37,6 +37,7 @@ ORBCORE_SRCS = \ CDR \ Client_Strategy_Factory \ Connect \ + append \ debug \ decode \ deep_copy \ diff --git a/TAO/tao/Marshal.h b/TAO/tao/Marshal.h index a30e3d500b7..e437522b242 100644 --- a/TAO/tao/Marshal.h +++ b/TAO/tao/Marshal.h @@ -117,6 +117,12 @@ public: CORBA::Environment &env) = 0; // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) = 0; + // append operation + TAO_Marshal_Object (void); // constructor @@ -158,6 +164,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_Any: public TAO_Marshal_Object @@ -194,6 +206,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_TypeCode: public TAO_Marshal_Object @@ -230,6 +248,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_Principal: public TAO_Marshal_Object @@ -266,6 +290,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_ObjRef: public TAO_Marshal_Object @@ -302,6 +332,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_Struct: public TAO_Marshal_Object @@ -338,6 +374,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_Union: public TAO_Marshal_Object @@ -374,6 +416,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_String: public TAO_Marshal_Object @@ -410,6 +458,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_Sequence: public TAO_Marshal_Object @@ -446,6 +500,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_Array: public TAO_Marshal_Object @@ -482,6 +542,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_Alias: public TAO_Marshal_Object @@ -518,6 +584,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_Except: public TAO_Marshal_Object @@ -553,6 +625,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; class TAO_Export TAO_Marshal_WString : public TAO_Marshal_Object @@ -588,6 +666,12 @@ public: CORBA::Environment &env); // skip operation + virtual CORBA::TypeCode::traverse_status append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env); + // append operation + }; #if defined (__ACE_INLINE__) diff --git a/TAO/tao/ORB.h b/TAO/tao/ORB.h index 9c67e96abc5..78d2eb130f7 100644 --- a/TAO/tao/ORB.h +++ b/TAO/tao/ORB.h @@ -488,8 +488,8 @@ public: typedef CORBA_UserException UserException; - typedef TAO_Unbounded_Object_Sequence ExceptionList; - typedef ExceptionList *ExceptionList_ptr; + typedef CORBA_ExceptionList ExceptionList; + typedef CORBA_ExceptionList *ExceptionList_ptr; typedef CORBA_ImplementationDef *ImplementationDef_ptr; diff --git a/TAO/tao/Typecode.cpp b/TAO/tao/Typecode.cpp index 454cc1333d5..9cfdbc5489e 100644 --- a/TAO/tao/Typecode.cpp +++ b/TAO/tao/Typecode.cpp @@ -33,12 +33,12 @@ CORBA_TypeCode::_duplicate (CORBA::TypeCode_ptr tc) return tc; } -CORBA_Bounds::CORBA_Bounds (void) +CORBA_TypeCode::Bounds::Bounds (void) : CORBA_UserException (CORBA::_tc_Bounds) { } -CORBA_BadKind::CORBA_BadKind (void) +CORBA_TypeCode::BadKind::BadKind (void) : CORBA_UserException (CORBA::_tc_BadKind) { } diff --git a/TAO/tao/Typecode.h b/TAO/tao/Typecode.h index 21f423ff497..196b26c2f49 100644 --- a/TAO/tao/Typecode.h +++ b/TAO/tao/Typecode.h @@ -23,24 +23,6 @@ // Forward decl. class TAO_InputCDR; -// Two "user exceptions" are defined for manipulating TypeCodes. These -// two classes are really to be defined inside the TypeCode class. -// @@ Andy, can you please explain why they aren't defined there? - -//extern CORBA::TypeCode_ptr CORBA::_tc_Bounds; -class CORBA_Bounds : public CORBA_UserException -{ -public: - CORBA_Bounds (void); -}; - -//extern CORBA::TypeCode_ptr CORBA::_tc_BadKind; -class CORBA_BadKind : public CORBA_UserException -{ -public: - CORBA_BadKind (void); -}; - // A TypeCode describes data. This one's as thin a wrapper around CDR // octet sequences as is practical. There are guesses here about how // the OMG C++ mapping and CORBA 2.0 IFR specification will interact. @@ -52,6 +34,7 @@ public: class TC_Private_State; class TAO_Export CORBA_TypeCode +{ // = TITLE // The CORBA TypeCode class. It maintains the in-memory // representation of any OMG CORBA IDL data type. @@ -70,17 +53,25 @@ class TAO_Export CORBA_TypeCode // THREADING NOTE: Typecodes are readonly data structures, and the // only mutual exclusion relates to reference counting and // construction. -{ public: + + // Two "user exceptions" are defined for manipulating TypeCodes. These + // two classes are defined inside the TypeCode class. + class Bounds : public CORBA_UserException + { + public: + Bounds (void); + }; + + class BadKind : public CORBA_UserException + { + public: + BadKind (void); + }; + void operator delete (void*); // Help debug free-non-heap-memory problems. - typedef CORBA_Bounds Bounds; - typedef CORBA_BadKind BadKind; - // As per the spec, these two exception classes are supposed to be - // nested inside the TypeCode class. Since we are trying to avoid - // nesting of classes, we use the above typedef. - static CORBA::TypeCode_ptr _duplicate (CORBA::TypeCode_ptr tc); // Duplicates i.e., increments ref count. diff --git a/TAO/tao/append.cpp b/TAO/tao/append.cpp new file mode 100644 index 00000000000..7182867da7e --- /dev/null +++ b/TAO/tao/append.cpp @@ -0,0 +1,705 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// append.cpp +// +// = DESCRIPTION +// Appends a CDR stream to another CDR stream. Due to the stringent alignment +// requirements, it is not possible to simply append or memcpy. Instead we go +// thru the same CDR encoding rules +// +// = AUTHOR +// Copyright 1994-1995 by Sun Microsystems Inc. +// and Aniruddha Gokhale +// +// ============================================================================ + +#include "tao/corba.h" + +extern CORBA::TypeCode TC_opaque; + +// Encode instances of arbitrary data types based only on typecode. +// "data" points to the data type; if it's not a primitve data type, +// the TypeCode interpreter is used to recursively encode its +// components. "context" is the marshaling stream on which to encode +// the data value. + +CORBA::TypeCode::traverse_status +TAO_Marshal_Primitive::append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::Boolean continue_append = CORBA::B_TRUE; + CORBA::TypeCode::traverse_status retval = + CORBA::TypeCode::TRAVERSE_CONTINUE; // status of encode operation + + switch (tc->kind_) + { + case CORBA::tk_null: + case CORBA::tk_void: + break; + case CORBA::tk_short: + case CORBA::tk_ushort: + continue_append = dest->append_short (*src); + break; + case CORBA::tk_long: + case CORBA::tk_ulong: + case CORBA::tk_float: + case CORBA::tk_enum: + continue_append = dest->append_long (*src); + break; + case CORBA::tk_double: + case CORBA::tk_longlong: + case CORBA::tk_ulonglong: + continue_append = dest->append_double (*src); + break; + case CORBA::tk_boolean: + continue_append = dest->append_boolean (*src); + break; + case CORBA::tk_char: + case CORBA::tk_octet: + continue_append = dest->append_octet (*src); + break; + case CORBA::tk_longdouble: + continue_append = dest->append_longdouble (*src); + break; + case CORBA::tk_wchar: + continue_append = dest->append_wchar (*src); + break; + default: + retval = CORBA::TypeCode::TRAVERSE_STOP; + // we are not a primitive type + } + + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE + && continue_append == CORBA::B_TRUE) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + dmsg ("TAO_Marshal_Primitive::encode detected error"); + return CORBA::TypeCode::TRAVERSE_STOP; + } +} + +CORBA::TypeCode::traverse_status +TAO_Marshal_Any::append (CORBA::TypeCode_ptr, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + // Typecode of the element that makes the Any. + CORBA::TypeCode_ptr elem_tc; + + // Status of append operation. + CORBA::TypeCode::traverse_status retval = + CORBA::TypeCode::TRAVERSE_CONTINUE; + + // Decode the typecode description for the element so that we can append the + // data appropriately + if ((retval = src->decode (CORBA::_tc_TypeCode, + &elem_tc, + 0, + env)) + == CORBA::TypeCode::TRAVERSE_CONTINUE) + { + // encode the typecode + retval = dest->encode (CORBA::_tc_TypeCode, &elem_tc, 0, env); + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + // append the data + retval = dest->append (elem_tc, src, env); + } + if (retval != CORBA::TypeCode::TRAVERSE_CONTINUE) + { + CORBA::release (elem_tc); + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + dmsg ("TAO_Marshal_Any::append detected error"); + } + return retval; +} + +CORBA::TypeCode::traverse_status +TAO_Marshal_TypeCode::append (CORBA::TypeCode_ptr, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::Boolean continue_append = CORBA::B_TRUE; + CORBA::TypeCode::traverse_status retval = + CORBA::TypeCode::TRAVERSE_CONTINUE; + CORBA::ULong kind; + + // Decode the "kind" field of the typecode from the src for further + // use. However, also write it back into the destination + continue_append = (src->read_ulong (kind) ? dest->write_ulong (kind) : 0); + + if (continue_append == CORBA::B_TRUE) + { + // Typecodes with empty parameter lists all have preallocated + // constants. We use those to reduce memory consumption and + // heap access ... also, to speed things up! + if ((kind < CORBA::TC_KIND_COUNT) + || (kind == ~(CORBA::ULong)0)) + { + // Either a non-constant typecode or an indirected typecode. + switch (kind) + { + // Need special handling for all kinds of typecodes that + // have nonempty parameter lists ... + default: + // nothing to de done + break; + case CORBA::tk_string: + case CORBA::tk_wstring: + { + // read and write the bounds + retval = dest->append (CORBA::_tc_long, src, env); + } + break; + + // Indirected typecodes, illegal at "top level" + case ~0: + { + // read and write the negative offset + retval = dest->append (CORBA::_tc_long, src, env); + } + break; + + // The rest have "complex" parameter lists that are + // encoded as bulk octets ... + case CORBA::tk_objref: + case CORBA::tk_struct: + case CORBA::tk_union: + case CORBA::tk_enum: + case CORBA::tk_sequence: + case CORBA::tk_array: + case CORBA::tk_alias: + case CORBA::tk_except: + { + // write the encapsulation i.e., octet sequence + retval = dest->append (&TC_opaque, src, env); + } + } // end of switch + } + else // bad kind_ value to be decoded + { + env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); + dmsg ("TAO_Marshal_TypeCode: Bad kind_ value in CDR stream"); + return CORBA::TypeCode::TRAVERSE_STOP; + } + } + + if ((continue_append == CORBA::B_TRUE) && + (retval == CORBA::TypeCode::TRAVERSE_CONTINUE)) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + dmsg ("TAO_Marshal_TypeCode::append detected error"); + return CORBA::TypeCode::TRAVERSE_STOP; + } +} + +// Encode Principal. + +CORBA::TypeCode::traverse_status +TAO_Marshal_Principal::append (CORBA::TypeCode_ptr, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + // write the octet sequence representing the Principal + return dest->append (&TC_opaque, src, env); +} + +CORBA::TypeCode::traverse_status +TAO_Marshal_ObjRef::append (CORBA::TypeCode_ptr, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::Boolean continue_append = CORBA::B_TRUE; + + // First, append the type hint. This will be the type_id encoded in an + // object reference. + dest->append_string (*src); + + // Read the profiles, discarding all until an IIOP profile comes by. + // Once we see an IIOP profile, ignore any further ones. + // + // XXX this will need to change someday to let different protocol + // code be accessed, not just IIOP. Protocol modules will be + // dynamically loaded from shared libraries via ORB_init (), and we + // just need to be able to access such preloaded libraries here as + // we unmarshal objrefs. + + CORBA::ULong profiles; + + // get the count of profiles that follow. This will tell us the length of the + // sequence + continue_append = (src->read_ulong (profiles) ? + dest->write_ulong (profiles) : 0); + + // No profiles means a NIL objref. + while (profiles-- != 0 && continue_append) + { + CORBA::ULong tag; + + // get the profile ID tag + if ((continue_append = (src->read_ulong (tag) ? + dest->write_ulong (tag) : 0)) + == CORBA::B_FALSE) + continue; + + if (tag != TAO_IOP_TAG_INTERNET_IOP) + { + continue_append = dest->append_string (*src); + continue; + } + + // OK, we've got an IIOP profile. It's going to be + // encapsulated ProfileData. Create a new decoding stream and + // context for it, and tell the "parent" stream that this data + // isn't part of it any more. + + // ProfileData is encoded as an encapsulated sequence of octets. + continue_append = (dest->append (&TC_opaque, src, env) == + CORBA::TypeCode::TRAVERSE_CONTINUE) ? 1 : 0; + } + + if (continue_append == CORBA::B_TRUE) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + ACE_DEBUG ((LM_DEBUG, "marshaling decode_objref detected error")); + return CORBA::TypeCode::TRAVERSE_STOP; + } +} + +// Decode structs. +CORBA::TypeCode::traverse_status +TAO_Marshal_Struct::append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::TypeCode::traverse_status retval = + CORBA::TypeCode::TRAVERSE_CONTINUE; + CORBA::Boolean continue_append = CORBA::B_TRUE; + CORBA::TypeCode_ptr param; + + // Number of fields in the struct. + int member_count = tc->member_count (env); + + if (env.exception () == 0) + for (int i = 0; i < member_count + && retval == CORBA::TypeCode::TRAVERSE_CONTINUE + && continue_append == CORBA::B_TRUE; + i++) + { + // get member type + param = tc->member_type (i, env); + if (env.exception () == 0) + { + retval = dest->append (param, src, env); + } + else + return CORBA::TypeCode::TRAVERSE_STOP; + } + else + return CORBA::TypeCode::TRAVERSE_STOP; + + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE + && continue_append == CORBA::B_TRUE) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + dmsg ("marshaling encode_struct detected error"); + return CORBA::TypeCode::TRAVERSE_STOP; + } +} + +// Encode unions. +CORBA::TypeCode::traverse_status +TAO_Marshal_Union::append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::TypeCode::traverse_status retval = + CORBA::TypeCode::TRAVERSE_CONTINUE; + + CORBA::TypeCode_ptr discrim_tc; + CORBA::TypeCode_ptr member_tc; + CORBA::Any_ptr member_label; + CORBA::Long discrim_val; + CORBA::ULong member_count; + CORBA::Long default_index; + CORBA::ULong i; + CORBA::TypeCode_ptr default_tc = 0; + CORBA::Boolean discrim_matched = CORBA::B_FALSE; + + // get the discriminator type + discrim_tc = tc->discriminator_type (env); + + if (env.exception () == 0) + { + // decode the discriminator value + retval = src->decode (discrim_tc, &discrim_val, 0, env); + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + { + // write the discriminant back to the dest + retval = dest->encode (discrim_tc, &discrim_val, 0, env); + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + { + // now get ready to marshal the actual union value + default_index = tc->default_index (env); + + if (env.exception () == 0) + { + member_count = tc->member_count (env); + if (env.exception () == 0) + { + // check which label value matches with the discriminator + // value. Accordingly, marshal the corresponding + // member_type. If none match, check if default exists + // and marshal accordingly. Otherwise it is an error. + + for (i = 0; member_count-- != 0; i++) + { + member_label = tc->member_label (i, env); + if (env.exception () == 0) + { + // do the matching + switch (member_label->type ()->kind (env)) + { + case CORBA::tk_short: + case CORBA::tk_ushort: + if (*(CORBA::Short *) member_label->value () == + *(CORBA::Short *) &discrim_val) + discrim_matched = CORBA::B_TRUE; + break; + case CORBA::tk_long: + case CORBA::tk_ulong: + case CORBA::tk_enum: + if (*(CORBA::ULong *) member_label->value () == + *(CORBA::ULong *) &discrim_val) + discrim_matched = CORBA::B_TRUE; + break; + case CORBA::tk_char: + if (*(CORBA::Char *) member_label->value () == + *(CORBA::Char *) &discrim_val) + discrim_matched = CORBA::B_TRUE; + break; + case CORBA::tk_wchar: + if (*(CORBA::WChar *) member_label->value () == + *(CORBA::WChar *) &discrim_val) + discrim_matched = CORBA::B_TRUE; + break; + case CORBA::tk_boolean: + if (*(CORBA::Boolean *) member_label->value () == + *(CORBA::Boolean *) &discrim_val) + discrim_matched = CORBA::B_TRUE; + break; + default: + env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); + return CORBA::TypeCode::TRAVERSE_STOP; + }// end of switch + + // get the member typecode + member_tc = tc->member_type (i, env); + if (env.exception () == 0) + { + if (default_index >= 0 && default_index-- == 0) + // have we reached the default label?, if so, + // save a handle to the typecode for the default + default_tc = member_tc; + if (discrim_matched) + // marshal according to the matched typecode + return dest->append (member_tc, src, env); + } + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + return CORBA::TypeCode::TRAVERSE_STOP; + } + } + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + return CORBA::TypeCode::TRAVERSE_STOP; + } + } // end of for loop + // we are here only if there was no match + if (default_tc) + return dest->append (default_tc, src, env); + else + return CORBA::TypeCode::TRAVERSE_CONTINUE; + } + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + return CORBA::TypeCode::TRAVERSE_STOP; + } + } + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + return CORBA::TypeCode::TRAVERSE_STOP; + } + } + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + return CORBA::TypeCode::TRAVERSE_STOP; + } + } + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + return CORBA::TypeCode::TRAVERSE_STOP; + } + } + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + return CORBA::TypeCode::TRAVERSE_STOP; + } +} + +// decode string +CORBA::TypeCode::traverse_status +TAO_Marshal_String::append (CORBA::TypeCode_ptr, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::Boolean continue_append = CORBA::B_TRUE; + + // On decode, omit the check against specified string bounds, and + // cope with illegal "zero length" strings (all lengths on the wire + // must include a NUL). + // + // This is on the principle of being gracious in what we accept; we + // don't generate messages that fail to comply with protocol specs, + // but we will accept them when it's clear how to do so. + + continue_append = dest->append_string (*src); + if (continue_append == CORBA::B_TRUE) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + dmsg ("TAO_Marshal_TypeCode::append detected error"); + return CORBA::TypeCode::TRAVERSE_STOP; + } +} + +// Decode sequence. + +CORBA::TypeCode::traverse_status +TAO_Marshal_Sequence::append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::Boolean continue_append = CORBA::B_TRUE; + // Return status. + CORBA::TypeCode::traverse_status retval = + CORBA::TypeCode::TRAVERSE_CONTINUE; + // Typecode of the element. + CORBA::TypeCode_ptr tc2; + // Size of element. + CORBA::ULong bounds; + + // First unmarshal the sequence length ... we trust it to be right + // here, on the "be gracious in what you accept" principle. We + // don't generate illegal sequences (i.e. length > bounds). + + continue_append = (src->read_ulong (bounds) ? + dest->write_ulong (bounds) : 0); + + if (continue_append) + { + // Get element typecode. + tc2 = tc->content_type (env); + + if (env.exception () == 0) + { + // For those aggregate types whose size is + // constant, we compute it only once. + while (bounds-- && retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + { + retval = dest->append (tc2, src, env); + } + // CORBA::release (tc2); + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + } // no exception computing content type + } + // error exit + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); + dmsg ("marshaling TAO_Marshal_Sequence::append detected error"); + return CORBA::TypeCode::TRAVERSE_STOP; +} + +// Decode array. + +CORBA::TypeCode::traverse_status +TAO_Marshal_Array::append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::Boolean continue_append = CORBA::B_TRUE; + + // Return status. + CORBA::TypeCode::traverse_status retval = + CORBA::TypeCode::TRAVERSE_CONTINUE; + + // Typecode of the element. + CORBA::TypeCode_ptr tc2; + + CORBA::ULong bounds; + + // retrieve the bounds of the array + bounds = tc->length (env); + if (env.exception () == 0) + { + // get element typecode + tc2 = tc->content_type (env); + if (env.exception () == 0) + { + while (bounds-- && retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + { + retval = dest->append (tc2, src, env); + } + // CORBA::release (tc2); + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + } // no exception computing content type + } // no exception computing bounds + // error exit + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); + dmsg ("marshaling TAO_Marshal_Sequence::append detected error"); + return CORBA::TypeCode::TRAVERSE_STOP; +} + +// Decode alias. +CORBA::TypeCode::traverse_status +TAO_Marshal_Alias::append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + // Typecode of the aliased type. + CORBA::TypeCode_ptr tc2; + CORBA::Boolean continue_append = CORBA::B_TRUE; + + // Status of decode operation. + CORBA::TypeCode::traverse_status retval = + CORBA::TypeCode::TRAVERSE_CONTINUE; + + tc2 = tc->content_type (env); + if (env.exception () == 0) + { + retval = dest->append (tc2, src, env); + } + + // tc2->Release (); + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE + && continue_append == CORBA::B_TRUE) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + dmsg ("TAO_Marshal_Alias::append detected error"); + return CORBA::TypeCode::TRAVERSE_STOP; + } +} + +// Decode exception For exceptions, the "hidden" type ID near the +// front of the on-wire representation was previously unmarshaled and +// mapped to the "tc" typcode we're using to traverse the memory ... +// at the same time its vtable, refcount, and other state was +// established. +// +// NOTE: This is asymmetric with respect to encoding exceptions. +CORBA::TypeCode::traverse_status +TAO_Marshal_Except::append (CORBA::TypeCode_ptr tc, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::TypeCode::traverse_status retval = + CORBA::TypeCode::TRAVERSE_CONTINUE; + CORBA::Boolean continue_append = CORBA::B_TRUE; + CORBA::TypeCode_ptr param; + + // Number of fields in the struct. + int member_count = tc->member_count (env); + if (env.exception () == 0) + { + for (int i = 0; i < member_count + && retval == CORBA::TypeCode::TRAVERSE_CONTINUE + && continue_append == CORBA::B_TRUE; i++) + { + param = tc->member_type (i, env); + if (env.exception () == 0) + { + retval = dest->append (param, src, env); + } + else + return CORBA::TypeCode::TRAVERSE_STOP; + } + } + else + return CORBA::TypeCode::TRAVERSE_STOP; + + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE + && continue_append == CORBA::B_TRUE) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + dmsg ("TAO_Marshal_Except detected error"); + return CORBA::TypeCode::TRAVERSE_STOP; + } +} + +// decode wstring +CORBA::TypeCode::traverse_status +TAO_Marshal_WString::append (CORBA::TypeCode_ptr, + TAO_InputCDR *src, + TAO_OutputCDR *dest, + CORBA::Environment &env) +{ + CORBA::Boolean continue_append = CORBA::B_TRUE; + + // On decode, omit the check against specified wstring bounds, and + // cope with illegal "zero length" strings (all lengths on the wire + // must include a NUL). + // + // This is on the principle of being gracious in what we accept; we + // don't generate messages that fail to comply with protocol specs, + // but we will accept them when it's clear how to do so. + + continue_append = dest->append_wstring (*src); + + if (continue_append == CORBA::B_TRUE) + return CORBA::TypeCode::TRAVERSE_CONTINUE; + else + { + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE)); + dmsg ("TAO_Marshal_TypeCode::append detected error"); + return CORBA::TypeCode::TRAVERSE_STOP; + } +} diff --git a/TAO/tao/corba.h b/TAO/tao/corba.h index 321cb5c23ba..61ea982e9c2 100644 --- a/TAO/tao/corba.h +++ b/TAO/tao/corba.h @@ -46,6 +46,7 @@ #include "ace/SOCK_Acceptor.h" #include "ace/Synch.h" #include "ace/Svc_Handler.h" +#include "ace/Containers.h" #if !defined (TAO_HAS_DLL) // On Windows NT, the default is to build TAO as a DLL library. @@ -137,6 +138,8 @@ typedef class CORBA_InterfaceDef *CORBA_InterfaceDef_ptr; class CORBA_String_var; +class CORBA_ExceptionList; + // enum values defined in nvlist.hh, bitwise ORed. typedef u_int CORBA_Flags; diff --git a/TAO/tao/decode.cpp b/TAO/tao/decode.cpp index cd3d0e0c7ec..a344f721221 100644 --- a/TAO/tao/decode.cpp +++ b/TAO/tao/decode.cpp @@ -171,7 +171,8 @@ TAO_Marshal_Any::decode (CORBA::TypeCode_ptr, == CORBA::TypeCode::TRAVERSE_CONTINUE) { // Let the Any maintain a pointer to the CDR stream - any->value_ = (ACE_Message_Block *) stream->start (); + any->value_ = ACE_Message_Block::duplicate ((ACE_Message_Block *) + stream->start ()); any->any_owns_data_ = 1; elem_tc->AddRef (); any->type_ = elem_tc; @@ -415,7 +416,7 @@ TAO_Marshal_Principal::decode (CORBA::TypeCode_ptr, CORBA::TypeCode::TRAVERSE_CONTINUE); (*pp)->id.length (len); - continue_decoding = + continue_decoding = stream->read_octet_array ((*pp)->id.get_buffer (), len); } diff --git a/TAO/tao/encode.cpp b/TAO/tao/encode.cpp index 87237209392..5f609268cc9 100644 --- a/TAO/tao/encode.cpp +++ b/TAO/tao/encode.cpp @@ -108,8 +108,6 @@ TAO_Marshal_Any::encode (CORBA::TypeCode_ptr, // Value maintained by the Any. void *value; - CORBA::Boolean continue_encoding = CORBA::B_TRUE; - TAO_OutputCDR *stream = (TAO_OutputCDR *) context; // Status of encode operation @@ -122,64 +120,21 @@ TAO_Marshal_Any::encode (CORBA::TypeCode_ptr, if (stream->encode (CORBA::_tc_TypeCode, &elem_tc, 0, env) == CORBA::TypeCode::TRAVERSE_CONTINUE) { value = (void *) any->value (); - - // Switch on the data type and handle the cases for primitives - // here for efficiency rather than calling. - switch (elem_tc->kind_) + // if the any owns the data, then the value is a CDR stream and we simply + // append the CDR stream + if (any->any_owns_data_) { - case CORBA::tk_null: - case CORBA::tk_void: - break; - case CORBA::tk_short: - case CORBA::tk_ushort: - continue_encoding = stream->write_short (*(CORBA::Short *) value); - break; - case CORBA::tk_long: - case CORBA::tk_ulong: - case CORBA::tk_float: - case CORBA::tk_enum: - continue_encoding = stream->write_long (*(CORBA::Long *) value); - break; - case CORBA::tk_double: - case CORBA::tk_longlong: - case CORBA::tk_ulonglong: - continue_encoding = stream->write_longlong (*(CORBA::LongLong *) value); - break; - case CORBA::tk_boolean: - continue_encoding = stream->write_boolean (*(CORBA::Boolean *) value); - break; - case CORBA::tk_char: - case CORBA::tk_octet: - continue_encoding = stream->write_char (*(CORBA::Char *) value); - break; - case CORBA::tk_longdouble: - continue_encoding = stream->write_longdouble (*(CORBA::LongDouble *) value); - break; - case CORBA::tk_wchar: - continue_encoding = stream->write_wchar (*(CORBA::WChar *) value); - break; - case CORBA::tk_any: - case CORBA::tk_TypeCode: - case CORBA::tk_Principal: - case CORBA::tk_objref: - case CORBA::tk_struct: - case CORBA::tk_union: - case CORBA::tk_string: - case CORBA::tk_sequence: - case CORBA::tk_array: - case CORBA::tk_alias: - case CORBA::tk_except: - case CORBA::tk_wstring: - retval = stream->encode (elem_tc, value, 0, env); - break; - default: - // anything else is an error - retval = CORBA::TypeCode::TRAVERSE_STOP; + TAO_InputCDR in_strm ((ACE_Message_Block *) any->value_); + retval = stream->append (elem_tc, &in_strm, env); + } + else + { + // encode the value + retval = stream->encode (elem_tc, any->value_, 0, env); } } - if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE - && continue_encoding == CORBA::B_TRUE) + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) return CORBA::TypeCode::TRAVERSE_CONTINUE; else { @@ -359,7 +314,7 @@ TAO_Marshal_ObjRef::encode (CORBA::TypeCode_ptr, u_int hostlen; hostlen = ACE_OS::strlen ((char *) profile->host); - CORBA::ULong encap_len = + CORBA::ULong encap_len = 1 // byte order + 1 // version major + 1 // version minor @@ -1132,7 +1087,7 @@ TAO_Marshal_Except::encode (CORBA::TypeCode_ptr tc, CORBA::Long size, alignment; // first encode the RepositoryID which we can grab from the - // typecode pointer + // typecode pointer continue_encoding = stream->write_string (tc->id (env)); data = (char *) data + sizeof (CORBA::Exception); diff --git a/TAO/tao/skip.cpp b/TAO/tao/skip.cpp index 7bd33e93642..787e11944c3 100644 --- a/TAO/tao/skip.cpp +++ b/TAO/tao/skip.cpp @@ -431,29 +431,29 @@ TAO_Marshal_Union::skip (CORBA::TypeCode_ptr tc, case CORBA::tk_short: case CORBA::tk_ushort: if (*(CORBA::Short *) member_label->value () == - *(CORBA::Short *) discrim_val) + *(CORBA::Short *) &discrim_val) discrim_matched = CORBA::B_TRUE; break; case CORBA::tk_long: case CORBA::tk_ulong: case CORBA::tk_enum: if (*(CORBA::ULong *) member_label->value () == - *(CORBA::ULong *) discrim_val) + *(CORBA::ULong *) &discrim_val) discrim_matched = CORBA::B_TRUE; break; case CORBA::tk_char: if (*(CORBA::Char *) member_label->value () == - *(CORBA::Char *) discrim_val) + *(CORBA::Char *) &discrim_val) discrim_matched = CORBA::B_TRUE; break; case CORBA::tk_wchar: if (*(CORBA::WChar *) member_label->value () == - *(CORBA::WChar *) discrim_val) + *(CORBA::WChar *) &discrim_val) discrim_matched = CORBA::B_TRUE; break; case CORBA::tk_boolean: if (*(CORBA::Boolean *) member_label->value () == - *(CORBA::Boolean *) discrim_val) + *(CORBA::Boolean *) &discrim_val) discrim_matched = CORBA::B_TRUE; break; default: -- cgit v1.2.1