Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

TAO_CDR_Encaps_Codec Class Reference

Implementation of a CDR encapsulation coder/decoder (Codec). More...

#include <CDR_Encaps_Codec.h>

Inheritance diagram for TAO_CDR_Encaps_Codec:

Inheritance graph
[legend]
Collaboration diagram for TAO_CDR_Encaps_Codec:

Collaboration graph
[legend]
List of all members.

Public Methods

 TAO_CDR_Encaps_Codec (CORBA::Octet major, CORBA::Octet minor, TAO_ORB_Core *orb_core)
 Constructor. More...

virtual CORBA::OctetSeqencode (const CORBA::Any &data ACE_ENV_ARG_DECL_WITH_DEFAULTS) throw (CORBA::SystemException, IOP::Codec::InvalidTypeForEncoding)
 Encode the given data, including the TypeCode, into an octet sequence. More...

virtual CORBA::Anydecode (const CORBA::OctetSeq &data ACE_ENV_ARG_DECL_WITH_DEFAULTS) throw (CORBA::SystemException, IOP::Codec::FormatMismatch)
 Extract the TypeCode and the value from the octet sequence and place them into an Any. More...

virtual CORBA::OctetSeqencode_value (const CORBA::Any &data ACE_ENV_ARG_DECL_WITH_DEFAULTS) throw (CORBA::SystemException, IOP::Codec::InvalidTypeForEncoding)
 Encode the given data, excluding the TypeCode, into an octet sequence. More...

virtual CORBA::Anydecode_value (const CORBA::OctetSeq &data, CORBA::TypeCode_ptr tc ACE_ENV_ARG_DECL_WITH_DEFAULTS) throw (CORBA::SystemException, IOP::Codec::FormatMismatch, IOP::Codec::TypeMismatch)
 Extract the value from the octet sequence, based on the given TypeCode, and place it into an Any. More...


Protected Methods

 ~TAO_CDR_Encaps_Codec (void)
 Destructor. More...

void check_type_for_encoding (const CORBA::Any &data ACE_ENV_ARG_DECL)
 Verify that it is possible to encode the given data using this Codec. More...


Private Methods

 TAO_CDR_Encaps_Codec (const TAO_CDR_Encaps_Codec &)
 Prevent copying through the copy constructor and the assignment operator. More...

void operator= (const TAO_CDR_Encaps_Codec &)

Private Attributes

CORBA::Octet major_
 The major GIOP version associated with this Codec. More...

CORBA::Octet minor_
 The minor GIOP version associated with this Codec. More...

TAO_ORB_Coreorb_core_
 The ORB Core to be used when decoding values from a CDR encapsulation. More...


Detailed Description

Implementation of a CDR encapsulation coder/decoder (Codec).

This coder/decoder (Codec) class encodes and decodes data to and from a CDR encapsulation, respectively. It is useful for creation of octet sequences that contain CDR encapsulations. Those octet sequences can then be placed in a IOP::ServiceContext or an IOP::TaggedComponent, for example.

Note:
This Codec should not be used for operations internal to the ORB core since it uses interpretive marshaling rather than compiled marshaling.

Definition at line 53 of file CDR_Encaps_Codec.h.


Constructor & Destructor Documentation

TAO_CDR_Encaps_Codec::TAO_CDR_Encaps_Codec CORBA::Octet    major,
CORBA::Octet    minor,
TAO_ORB_Core   orb_core
 

Constructor.

Definition at line 19 of file CDR_Encaps_Codec.cpp.

00022   : major_ (major),
00023     minor_ (minor),
00024     orb_core_ (orb_core)
00025 {
00026 }

TAO_CDR_Encaps_Codec::~TAO_CDR_Encaps_Codec void    [protected]
 

Destructor.

Only allow this class to be instantiated on the heap since it is reference counted.

Definition at line 28 of file CDR_Encaps_Codec.cpp.

00029 {
00030 }

TAO_CDR_Encaps_Codec::TAO_CDR_Encaps_Codec const TAO_CDR_Encaps_Codec &    [private]
 

Prevent copying through the copy constructor and the assignment operator.


Member Function Documentation

void TAO_CDR_Encaps_Codec::check_type_for_encoding const CORBA::Any &data    ACE_ENV_ARG_DECL [protected]
 

Verify that it is possible to encode the given data using this Codec.

Typical reasons for failure include attempting to encode a type that isn't supported for the version of GIOP associated with this Codec.

Definition at line 332 of file CDR_Encaps_Codec.cpp.

References ACE_ENV_ARG_DECL, ACE_THROW, major_, and minor_.

00335 {
00336   // @@ TODO: Are there any other conditions we need to check?
00337 
00338   CORBA::TypeCode_var typecode = data.type ();
00339   if (this->major_ == 1
00340       && this->minor_ == 0
00341       && typecode->equivalent (CORBA::_tc_wstring))
00342     ACE_THROW (IOP::Codec::InvalidTypeForEncoding ());
00343 }

CORBA::Any * TAO_CDR_Encaps_Codec::decode const CORBA::OctetSeq &data    ACE_ENV_ARG_DECL_WITH_DEFAULTS throw (CORBA::SystemException, IOP::Codec::FormatMismatch) [virtual]
 

Extract the TypeCode and the value from the octet sequence and place them into an Any.

Implements IOP::Codec.

Definition at line 88 of file CDR_Encaps_Codec.cpp.

References CORBA_SystemException::_tao_minor_code, ACE_CDR_BYTE_ORDER, ACE_CHECK_RETURN, ACE_ENV_ARG_DECL, ACE_NEW_THROW_EX, ACE_THROW_RETURN, ACE_Message_Block::base, ACE_Message_Block::data_block, ACE_Message_Block::DONT_DELETE, ACE_CDR::MAX_ALIGNMENT, ACE_CDR::mb_align, ACE_OS_String::memcpy, ACE_Message_Block::rd_ptr, ACE_InputCDR::reset_byte_order, TAO_DEFAULT_MINOR_CODE, and ACE_Message_Block::wr_ptr.

00092 {
00093   // @todo How do we check for a format mismatch so that we can throw
00094   //       a IOP::Codec::FormatMismatch exception?
00095   // @todo Is this the best way to extract the Any from the OctetSeq?
00096 
00097   // Notice that we need to extract the TypeCode and the value from
00098   // the octet sequence, and place them into the Any.  We can't just
00099   // insert the octet sequence into the Any.
00100 
00101   ACE_Message_Block mb (data.length () + 2 * ACE_CDR::MAX_ALIGNMENT);
00102   ACE_CDR::mb_align (&mb);
00103 
00104   ACE_OS::memcpy (mb.rd_ptr (), data.get_buffer (), data.length ());
00105 
00106   size_t rd_pos = mb.rd_ptr () - mb.base ();
00107   size_t wr_pos = mb.wr_ptr () - mb.base () + data.length ();
00108 
00109   TAO_InputCDR cdr (mb.data_block (),
00110                     ACE_Message_Block::DONT_DELETE,
00111                     rd_pos,
00112                     wr_pos,
00113                     ACE_CDR_BYTE_ORDER,
00114                     this->major_,
00115                     this->minor_,
00116                     this->orb_core_);
00117 
00118   CORBA::Boolean byte_order;
00119   if (cdr >> TAO_InputCDR::to_boolean (byte_order))
00120     {
00121       cdr.reset_byte_order (ACE_static_cast (int, byte_order));
00122 
00123       CORBA::Any * any = 0;
00124       ACE_NEW_THROW_EX (any,
00125                         CORBA::Any,
00126                         CORBA::NO_MEMORY (
00127                                           CORBA_SystemException::_tao_minor_code (
00128                                             TAO_DEFAULT_MINOR_CODE,
00129                                             ENOMEM),
00130                                           CORBA::COMPLETED_NO));
00131       ACE_CHECK_RETURN (0);
00132 
00133       CORBA::Any_var safe_any = any;
00134 
00135       if (cdr >> (*any))
00136         return safe_any._retn ();
00137     }
00138 
00139   ACE_THROW_RETURN (IOP::Codec::FormatMismatch (), 0);
00140 }

CORBA::Any * TAO_CDR_Encaps_Codec::decode_value const CORBA::OctetSeq   data,
CORBA::TypeCode_ptr tc    ACE_ENV_ARG_DECL_WITH_DEFAULTS
throw (CORBA::SystemException, IOP::Codec::FormatMismatch, IOP::Codec::TypeMismatch) [virtual]
 

Extract the value from the octet sequence, based on the given TypeCode, and place it into an Any.

Implements IOP::Codec.

Definition at line 212 of file CDR_Encaps_Codec.cpp.

References CORBA_SystemException::_tao_minor_code, ACE_CDR_BYTE_ORDER, ACE_CHECK_RETURN, ACE_ENV_ARG_DECL, ACE_ENV_ARG_PARAMETER, ACE_NEW_THROW_EX, ACE_THROW_RETURN, ACE_Message_Block::base, ACE_InputCDR::byte_order, ACE_Message_Block::data_block, ACE_Message_Block::DONT_DELETE, ACE_CDR::MAX_ALIGNMENT, ACE_CDR::mb_align, ACE_OS_String::memcpy, TAO_Marshal_Object::perform_skip, ptr_arith_t, ACE_InputCDR::rd_ptr, ACE_Message_Block::rd_ptr, ACE_InputCDR::reset_byte_order, TAO_DEFAULT_MINOR_CODE, and ACE_Message_Block::wr_ptr.

00218 {
00219   // The ACE_CDR::mb_align() call can shift the rd_ptr by up
00220   // to ACE_CDR::MAX_ALIGNMENT-1 bytes. Similarly, the offset
00221   // adjustment can move the rd_ptr by up to the same amount.
00222   // We accommodate this by including
00223   // 2 * ACE_CDR::MAX_ALIGNMENT bytes of additional space in
00224   // the message block.
00225   ACE_Message_Block mb (data.length () + 2 * ACE_CDR::MAX_ALIGNMENT);
00226   ACE_CDR::mb_align (&mb);
00227 
00228   ACE_OS::memcpy (mb.rd_ptr (), data.get_buffer (), data.length ());
00229 
00230   // @todo How do we check for a type mismatch so that we can
00231   //       throw a IOP::Codec::TypeMismatch exception?
00232   //       @@ I added a check below.  See the comment.  I'm not sure
00233   //          if it is a valid check.
00234   //             -Ossama
00235 
00236   // @todo Most of this code was copied from
00237   //         operator>> (TAO_InputCDR &cdr, CORBA::Any &x)
00238   //       in Any.cpp.  Rather than copy the code, the code should be
00239   //       refactored to make it possible to use the given TypeCode
00240   //       rather than attempt to extract it from the CDR
00241   //       encapsulation.
00242 
00243   CORBA::ULong sequence_length = data.length ();
00244 
00245   size_t rd_pos = mb.rd_ptr () - mb.base ();
00246   size_t wr_pos = mb.wr_ptr () - mb.base () + data.length ();
00247 
00248   TAO_InputCDR cdr (mb.data_block (),
00249                     ACE_Message_Block::DONT_DELETE,
00250                     rd_pos,
00251                     wr_pos,
00252                     ACE_CDR_BYTE_ORDER,
00253                     this->major_,
00254                     this->minor_,
00255                     this->orb_core_);
00256 
00257   CORBA::Boolean byte_order;
00258   if (cdr >> TAO_InputCDR::to_boolean (byte_order))
00259     {
00260       cdr.reset_byte_order (ACE_static_cast (int, byte_order));
00261 
00262       // @@ (JP) The following code depends on the fact that
00263       //         TAO_InputCDR does not contain chained message blocks,
00264       //         otherwise <begin> and <end> could be part of
00265       //         different buffers!
00266 
00267       // This will be the start of a new message block.
00268       char *begin = cdr.rd_ptr ();
00269 
00270       // Skip over the next argument.
00271       CORBA::TypeCode::traverse_status status =
00272         TAO_Marshal_Object::perform_skip (tc,
00273                                           &cdr
00274                                           ACE_ENV_ARG_PARAMETER);
00275       ACE_CHECK_RETURN (0);  // @@ Should we throw a
00276                              //    IOP::Codec::TypeMismatch exception
00277                              //    here if this fails?
00278 
00279       if (status == CORBA::TypeCode::TRAVERSE_CONTINUE)
00280         {
00281           // This will be the end of the new message block.
00282           char *end = cdr.rd_ptr ();
00283 
00284           size_t size = end - begin;
00285 
00286           // @@ I added the following check, but I'm not sure if it is
00287           //    a valid check.  Can someone verify this?
00288           //          -Ossama
00289 
00290           // If the unaligned buffer size is not equal to the octet
00291           // sequence length (minus the "byte order byte") then the
00292           // TypeCode does not correspond to the data in the CDR
00293           // encapsulation.  However, even if they do match it is
00294           // still uncertain if the TypeCode corresponds to the data
00295           // in the octet sequence.  With this test, it is only
00296           // possible to determine if the TypeCode does *not* match
00297           // the data, not if it does match.
00298           if (size != sequence_length - 1)
00299             ACE_THROW_RETURN (IOP::Codec::TypeMismatch (), 0);
00300 
00301           ptr_arith_t offset =
00302             ptr_arith_t (begin) % ACE_CDR::MAX_ALIGNMENT;
00303           mb.rd_ptr (offset);
00304           mb.wr_ptr (offset + size);
00305 
00306           CORBA::Any * any = 0;
00307           ACE_NEW_THROW_EX (any,
00308                             CORBA::Any,
00309                             CORBA::NO_MEMORY (
00310                                               CORBA_SystemException::_tao_minor_code (
00311                                                 TAO_DEFAULT_MINOR_CODE,
00312                                                 ENOMEM),
00313                                               CORBA::COMPLETED_NO));
00314           ACE_CHECK_RETURN (0);
00315 
00316           CORBA::Any_var safe_any = any;
00317 
00318           // Stick it into the Any.  It gets duplicated there.
00319           any->_tao_replace (tc,
00320                              cdr.byte_order (),
00321                              &mb);
00322           return safe_any._retn ();
00323         }
00324       else
00325         ACE_THROW_RETURN (IOP::Codec::TypeMismatch (), 0);
00326     }
00327 
00328   ACE_THROW_RETURN (IOP::Codec::FormatMismatch (), 0);
00329 }

CORBA::OctetSeq * TAO_CDR_Encaps_Codec::encode const CORBA::Any &data    ACE_ENV_ARG_DECL_WITH_DEFAULTS throw (CORBA::SystemException, IOP::Codec::InvalidTypeForEncoding) [virtual]
 

Encode the given data, including the TypeCode, into an octet sequence.

Implements IOP::Codec.

Definition at line 33 of file CDR_Encaps_Codec.cpp.

References CORBA_SystemException::_tao_minor_code, ACE_CDR_BYTE_ORDER, ACE_CHECK_RETURN, ACE_ENV_ARG_DECL, ACE_ENV_ARG_PARAMETER, ACE_NEW_THROW_EX, ACE_THROW_RETURN, ACE_OutputCDR::begin, ACE_Message_Block::cont, ACE_Message_Block::length, ACE_OS_String::memcpy, ACE_Message_Block::rd_ptr, TAO_DEFAULT_MINOR_CODE, TAO_ENCAP_BYTE_ORDER, and ACE_OutputCDR::total_length.

00037 {
00038   this->check_type_for_encoding (data
00039                                  ACE_ENV_ARG_PARAMETER);
00040   ACE_CHECK_RETURN (0);
00041 
00042   // ----------------------------------------------------------------
00043 
00044   TAO_OutputCDR cdr ((size_t) 0,            // size
00045                      (int) ACE_CDR_BYTE_ORDER,
00046                      (ACE_Allocator *) 0,   // buffer_allocator
00047                      (ACE_Allocator *) 0,   // data_block_allocator
00048                      (ACE_Allocator *) 0,   // message_block_allocator
00049                      0,                     // memcpy_tradeoff
00050                      this->major_,
00051                      this->minor_);
00052 
00053   if ((cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
00054       && (cdr << data))
00055     {
00056       CORBA::OctetSeq * octet_seq = 0;
00057 
00058       ACE_NEW_THROW_EX (octet_seq,
00059                         CORBA::OctetSeq,
00060                         CORBA::NO_MEMORY (
00061                           CORBA_SystemException::_tao_minor_code (
00062                             TAO_DEFAULT_MINOR_CODE,
00063                             ENOMEM),
00064                           CORBA::COMPLETED_NO));
00065       ACE_CHECK_RETURN (0);
00066 
00067       CORBA::OctetSeq_var safe_octet_seq = octet_seq;
00068 
00069       octet_seq->length (ACE_static_cast(CORBA::ULong, cdr.total_length ()));
00070       CORBA::Octet *buf = octet_seq->get_buffer ();
00071 
00072       for (const ACE_Message_Block *i = cdr.begin ();
00073            i != 0;
00074            i = i->cont ())
00075         {
00076           size_t len = i->length ();
00077           ACE_OS_String::memcpy (buf, i->rd_ptr (), len);
00078           buf += len;
00079         }
00080 
00081       return safe_octet_seq._retn ();
00082     }
00083 
00084   ACE_THROW_RETURN (CORBA::MARSHAL (), 0);
00085 }

CORBA::OctetSeq * TAO_CDR_Encaps_Codec::encode_value const CORBA::Any &data    ACE_ENV_ARG_DECL_WITH_DEFAULTS throw (CORBA::SystemException, IOP::Codec::InvalidTypeForEncoding) [virtual]
 

Encode the given data, excluding the TypeCode, into an octet sequence.

Implements IOP::Codec.

Definition at line 143 of file CDR_Encaps_Codec.cpp.

References CORBA_SystemException::_tao_minor_code, ACE_CDR_BYTE_ORDER, ACE_CHECK_RETURN, ACE_ENV_ARG_DECL, ACE_ENV_ARG_PARAMETER, ACE_NEW_THROW_EX, ACE_THROW_RETURN, ACE_OutputCDR::begin, ACE_Message_Block::cont, ACE_Message_Block::length, ACE_OS_String::memcpy, TAO_Marshal_Object::perform_append, ACE_Message_Block::rd_ptr, TAO_DEFAULT_MINOR_CODE, TAO_ENCAP_BYTE_ORDER, and ACE_OutputCDR::total_length.

00147 {
00148   this->check_type_for_encoding (data
00149                                   ACE_ENV_ARG_PARAMETER);
00150   ACE_CHECK_RETURN (0);
00151 
00152   // ----------------------------------------------------------------
00153   TAO_OutputCDR cdr ((size_t) 0,            // size
00154                      (int) ACE_CDR_BYTE_ORDER,
00155                      (ACE_Allocator *) 0,   // buffer_allocator
00156                      (ACE_Allocator *) 0,   // data_block_allocator
00157                      (ACE_Allocator *) 0,   // message_block_allocator
00158                      0,                     // memcpy_tradeoff
00159                      this->major_,
00160                      this->minor_);
00161 
00162   if ((cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)))
00163     {
00164       CORBA::TypeCode_var tc = data.type ();
00165 
00166       TAO_InputCDR input (data._tao_get_cdr (),
00167                           data._tao_byte_order (),
00168                           this->major_,
00169                           this->minor_,
00170                           this->orb_core_);
00171 
00172       TAO_Marshal_Object::perform_append (tc.in (),
00173                                           &input,
00174                                           &cdr
00175                                           ACE_ENV_ARG_PARAMETER);
00176       ACE_CHECK_RETURN (0);
00177 
00178       // TAO extension: replace the contents of the octet sequence with
00179       // the CDR stream.
00180       CORBA::OctetSeq * octet_seq = 0;
00181 
00182       ACE_NEW_THROW_EX (octet_seq,
00183                         CORBA::OctetSeq,
00184                         CORBA::NO_MEMORY (
00185                           CORBA_SystemException::_tao_minor_code (
00186                             TAO_DEFAULT_MINOR_CODE,
00187                             ENOMEM),
00188                           CORBA::COMPLETED_NO));
00189       ACE_CHECK_RETURN (0);
00190 
00191       CORBA::OctetSeq_var safe_octet_seq = octet_seq;
00192 
00193       octet_seq->length (ACE_static_cast(CORBA::ULong, cdr.total_length ()));
00194       CORBA::Octet *buf = octet_seq->get_buffer ();
00195 
00196       for (const ACE_Message_Block *i = cdr.begin ();
00197            i != 0;
00198            i = i->cont ())
00199         {
00200           size_t len = i->length ();
00201           ACE_OS_String::memcpy (buf, i->rd_ptr (), len);
00202           buf += len;
00203         }
00204 
00205       return safe_octet_seq._retn ();
00206     }
00207 
00208   ACE_THROW_RETURN (CORBA::MARSHAL (), 0);
00209 }

void TAO_CDR_Encaps_Codec::operator= const TAO_CDR_Encaps_Codec &    [private]
 


Member Data Documentation

CORBA::Octet TAO_CDR_Encaps_Codec::major_ [private]
 

The major GIOP version associated with this Codec.

Definition at line 124 of file CDR_Encaps_Codec.h.

Referenced by check_type_for_encoding.

CORBA::Octet TAO_CDR_Encaps_Codec::minor_ [private]
 

The minor GIOP version associated with this Codec.

Definition at line 127 of file CDR_Encaps_Codec.h.

Referenced by check_type_for_encoding.

TAO_ORB_Core* TAO_CDR_Encaps_Codec::orb_core_ [private]
 

The ORB Core to be used when decoding values from a CDR encapsulation.

Definition at line 131 of file CDR_Encaps_Codec.h.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 15:06:18 2003 for TAO by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002