diff options
Diffstat (limited to 'TAO/tao/Any.cpp')
-rw-r--r-- | TAO/tao/Any.cpp | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/TAO/tao/Any.cpp b/TAO/tao/Any.cpp index 6ce0a706814..fc470c62668 100644 --- a/TAO/tao/Any.cpp +++ b/TAO/tao/Any.cpp @@ -337,11 +337,48 @@ void TAO::Unknown_IDL_Type::_tao_decode (TAO_InputCDR &cdr ACE_ENV_ARG_DECL) { + // @@ (JP) The following code depends on the fact that + // TAO_InputCDR does not contain chained message blocks, + // otherwise <begin> and <end> could be part of + // different buffers! + + // This will be the start of a new message block. + char *begin = cdr.rd_ptr (); + + // Skip over the next argument. + CORBA::TypeCode::traverse_status status = + TAO_Marshal_Object::perform_skip (this->type_, + &cdr + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (status != CORBA::TypeCode::TRAVERSE_CONTINUE) + { + ACE_THROW (CORBA::MARSHAL ()); + } + + // This will be the end of the new message block. + char *end = cdr.rd_ptr (); + + // The ACE_CDR::mb_align() call can shift the rd_ptr by up to + // ACE_CDR::MAX_ALIGNMENT-1 bytes. Similarly, the offset adjustment + // can move the rd_ptr by up to the same amount. We accommodate + // this by including 2 * ACE_CDR::MAX_ALIGNMENT bytes of additional + // space in the message block. + size_t size = end - begin; + ACE_Message_Block::release (this->cdr_); ACE_NEW (this->cdr_, - ACE_Message_Block); - ACE_CDR::consolidate (this->cdr_, - cdr.start ()); + ACE_Message_Block (size + 2 * ACE_CDR::MAX_ALIGNMENT)); + + ACE_CDR::mb_align (this->cdr_); + ptr_arith_t offset = ptr_arith_t (begin) % ACE_CDR::MAX_ALIGNMENT; + this->cdr_->rd_ptr (offset); + this->cdr_->wr_ptr (offset + size); + + ACE_OS::memcpy (this->cdr_->rd_ptr (), + begin, + size); } // **************************************************************** |