Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes

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 Member Functions

 TAO_CDR_Encaps_Codec (CORBA::Octet major, CORBA::Octet minor, TAO_ORB_Core *orb_core, TAO_Codeset_Translator_Base *char_trans, TAO_Codeset_Translator_Base *wchar_trans)
 Constructor.
virtual CORBA::OctetSeq * encode (const CORBA::Any &data)
virtual CORBA::Anydecode (const CORBA::OctetSeq &data)
virtual CORBA::OctetSeq * encode_value (const CORBA::Any &data)
virtual CORBA::Anydecode_value (const CORBA::OctetSeq &data, CORBA::TypeCode_ptr tc)

Protected Member Functions

virtual ~TAO_CDR_Encaps_Codec (void)
 Destructor.
void check_type_for_encoding (const CORBA::Any &data)

Private Member Functions

 TAO_CDR_Encaps_Codec (const TAO_CDR_Encaps_Codec &)
void operator= (const TAO_CDR_Encaps_Codec &)

Private Attributes

CORBA::Octet const major_
 The major GIOP version associated with this Codec.
CORBA::Octet const minor_
 The minor GIOP version associated with this Codec.
TAO_ORB_Core *const orb_core_
TAO_Codeset_Translator_Basechar_translator_
 Char codeset translator.
TAO_Codeset_Translator_Basewchar_translator_
 WChar codeset translator.

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 46 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,
TAO_Codeset_Translator_Base char_trans,
TAO_Codeset_Translator_Base wchar_trans 
)

Constructor.

Definition at line 28 of file CDR_Encaps_Codec.cpp.

  : major_ (major),
    minor_ (minor),
    orb_core_ (orb_core),
    char_translator_ (char_trans),
    wchar_translator_ (wchar_trans)
{
}

TAO_CDR_Encaps_Codec::~TAO_CDR_Encaps_Codec ( void   )  [protected, virtual]

Destructor.

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

Definition at line 42 of file CDR_Encaps_Codec.cpp.

{
}

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  )  [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.

{
  // @@ TODO: Are there any other conditions we need to check?

  CORBA::TypeCode_var typecode = data.type ();
  if (this->major_ == 1
      && this->minor_ == 0
      && typecode->equivalent (CORBA::_tc_wstring))
    throw IOP::Codec::InvalidTypeForEncoding ();
}

CORBA::Any * TAO_CDR_Encaps_Codec::decode ( const CORBA::OctetSeq &  data  )  [virtual]

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

Definition at line 105 of file CDR_Encaps_Codec.cpp.

{
  // @todo How do we check for a format mismatch so that we can throw
  //       a IOP::Codec::FormatMismatch exception?
  // @todo Is this the best way to extract the Any from the OctetSeq?

  // Notice that we need to extract the TypeCode and the value from
  // the octet sequence, and place them into the Any.  We can't just
  // insert the octet sequence into the Any.

  ACE_Message_Block mb (data.length () + 2 * ACE_CDR::MAX_ALIGNMENT);
  ACE_CDR::mb_align (&mb);

  ACE_OS::memcpy (mb.rd_ptr (), data.get_buffer (), data.length ());

  size_t rd_pos = mb.rd_ptr () - mb.base ();
  size_t wr_pos = mb.wr_ptr () - mb.base () + data.length ();

  TAO_InputCDR cdr (mb.data_block (),
                    ACE_Message_Block::DONT_DELETE,
                    rd_pos,
                    wr_pos,
                    ACE_CDR_BYTE_ORDER,
                    this->major_,
                    this->minor_,
                    this->orb_core_);

  if (this->char_translator_)
    {
      this->char_translator_->assign (&cdr);
    }
  if (this->wchar_translator_)
    {
      this->wchar_translator_->assign (&cdr);
    }

  CORBA::Boolean byte_order;
  if (cdr >> TAO_InputCDR::to_boolean (byte_order))
    {
      cdr.reset_byte_order (static_cast<int> (byte_order));

      CORBA::Any * any = 0;
      ACE_NEW_THROW_EX (any,
                        CORBA::Any,
                        CORBA::NO_MEMORY (
                          CORBA::SystemException::_tao_minor_code (
                            0,
                            ENOMEM),
                          CORBA::COMPLETED_NO));

      CORBA::Any_var safe_any = any;

      if (cdr >> (*any))
        return safe_any._retn ();
    }

  throw IOP::Codec::FormatMismatch ();
}

CORBA::Any * TAO_CDR_Encaps_Codec::decode_value ( const CORBA::OctetSeq &  data,
CORBA::TypeCode_ptr  tc 
) [virtual]

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

Definition at line 250 of file CDR_Encaps_Codec.cpp.

{
  // 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.
  ACE_Message_Block mb (data.length () + 2 * ACE_CDR::MAX_ALIGNMENT);
  ACE_CDR::mb_align (&mb);

  ACE_OS::memcpy (mb.rd_ptr (),
                  data.get_buffer (),
                  data.length ());

  // @todo How do we check for a type mismatch so that we can
  //       throw a IOP::Codec::TypeMismatch exception?
  //       @@ I added a check below.  See the comment.  I'm not sure
  //          if it is a valid check.
  //             -Ossama

  // @todo Most of this code was copied from
  //         operator>> (TAO_InputCDR &cdr, CORBA::Any &x)
  //       in Any.cpp.  Rather than copy the code, the code should be
  //       refactored to make it possible to use the given TypeCode
  //       rather than attempt to extract it from the CDR
  //       encapsulation.

  size_t rd_pos = mb.rd_ptr () - mb.base ();
  size_t wr_pos = mb.wr_ptr () - mb.base () + data.length ();

  TAO_InputCDR cdr (mb.data_block (),
                    ACE_Message_Block::DONT_DELETE,
                    rd_pos,
                    wr_pos,
                    ACE_CDR_BYTE_ORDER,
                    this->major_,
                    this->minor_,
                    this->orb_core_);

  if (this->char_translator_)
    {
      this->char_translator_->assign (&cdr);
    }
  if (this->wchar_translator_)
    {
      this->wchar_translator_->assign (&cdr);
    }

  CORBA::Boolean byte_order;

  if (cdr >> TAO_InputCDR::to_boolean (byte_order))
    {
      cdr.reset_byte_order (static_cast<int> (byte_order));

      CORBA::Any * any = 0;
      ACE_NEW_THROW_EX (any,
                        CORBA::Any,
                        CORBA::NO_MEMORY (
                            CORBA::SystemException::_tao_minor_code (
                                0,
                                ENOMEM
                              ),
                            CORBA::COMPLETED_NO
                          ));

      CORBA::Any_var safe_any = any;

      // Stick it into the Any.
      TAO::Unknown_IDL_Type *unk = 0;
      ACE_NEW_RETURN (unk,
                      TAO::Unknown_IDL_Type (tc, cdr),
                      0);
      any->replace (unk);
      return safe_any._retn ();
    }

  throw IOP::Codec::FormatMismatch ();
}

CORBA::OctetSeq * TAO_CDR_Encaps_Codec::encode ( const CORBA::Any data  )  [virtual]

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

Definition at line 47 of file CDR_Encaps_Codec.cpp.

{
  this->check_type_for_encoding (data);

  // ----------------------------------------------------------------

  TAO_OutputCDR cdr ((size_t) 0,            // size
                     (int) TAO_ENCAP_BYTE_ORDER,
                     (ACE_Allocator *) 0,   // buffer_allocator
                     (ACE_Allocator *) 0,   // data_block_allocator
                     (ACE_Allocator *) 0,   // message_block_allocator
                     0,                     // memcpy_tradeoff
                     this->major_,
                     this->minor_);

  if (this->char_translator_)
    {
      this->char_translator_->assign (&cdr);
    }
  if (this->wchar_translator_)
    {
      this->wchar_translator_->assign (&cdr);
    }

  if ((cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
      && (cdr << data))
    {
      CORBA::OctetSeq * octet_seq = 0;

      ACE_NEW_THROW_EX (octet_seq,
                        CORBA::OctetSeq,
                        CORBA::NO_MEMORY (
                          CORBA::SystemException::_tao_minor_code (
                            0,
                            ENOMEM),
                          CORBA::COMPLETED_NO));

      CORBA::OctetSeq_var safe_octet_seq = octet_seq;

      octet_seq->length (static_cast<CORBA::ULong> (cdr.total_length ()));
      CORBA::Octet *buf = octet_seq->get_buffer ();

      for (const ACE_Message_Block *i = cdr.begin ();
           i != 0;
           i = i->cont ())
        {
          size_t const len = i->length ();
          ACE_OS::memcpy (buf, i->rd_ptr (), len);
          buf += len;
        }

      return safe_octet_seq._retn ();
    }

  throw ::CORBA::MARSHAL ();
}

CORBA::OctetSeq * TAO_CDR_Encaps_Codec::encode_value ( const CORBA::Any data  )  [virtual]

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

Definition at line 165 of file CDR_Encaps_Codec.cpp.

{
  this->check_type_for_encoding (data);

  // ----------------------------------------------------------------
  TAO_OutputCDR cdr ((size_t) 0,            // size
                     (int) TAO_ENCAP_BYTE_ORDER,
                     (ACE_Allocator *) 0,   // buffer_allocator
                     (ACE_Allocator *) 0,   // data_block_allocator
                     (ACE_Allocator *) 0,   // message_block_allocator
                     0,                     // memcpy_tradeoff
                     this->major_,
                     this->minor_);

  if (this->char_translator_)
    {
      this->char_translator_->assign (&cdr);
    }
  if (this->wchar_translator_)
    {
      this->wchar_translator_->assign (&cdr);
    }

  if ((cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)))
    {
      TAO::Any_Impl *impl = data.impl ();

      if (impl->encoded ())
        {
          TAO::Unknown_IDL_Type * const unk =
            dynamic_cast<TAO::Unknown_IDL_Type *> (impl);

          if (!unk)
            throw ::CORBA::INTERNAL ();

          // We don't want unk's rd_ptr to move, in case we are shared by
          // another Any, so we use this to copy the state, not the buffer.
          TAO_InputCDR for_reading (unk->_tao_get_cdr ());

          TAO_Marshal_Object::perform_append (data._tao_get_typecode (),
                                              &for_reading,
                                              &cdr);
        }
      else
        {
          impl->marshal_value (cdr);
        }

      // TAO extension: replace the contents of the octet sequence with
      // the CDR stream.
      CORBA::OctetSeq * octet_seq = 0;

      ACE_NEW_THROW_EX (octet_seq,
                        CORBA::OctetSeq,
                        CORBA::NO_MEMORY (
                            CORBA::SystemException::_tao_minor_code (
                                0,
                                ENOMEM
                              ),
                            CORBA::COMPLETED_NO
                          ));

      CORBA::OctetSeq_var safe_octet_seq = octet_seq;

      octet_seq->length (static_cast<CORBA::ULong> (cdr.total_length ()));
      CORBA::Octet *buf = octet_seq->get_buffer ();

      for (const ACE_Message_Block *i = cdr.begin ();
           i != 0;
           i = i->cont ())
        {
          size_t len = i->length ();
          ACE_OS::memcpy (buf,
                          i->rd_ptr (),
                          len);
          buf += len;
        }

      return safe_octet_seq._retn ();
    }

  throw ::CORBA::MARSHAL ();
}

void TAO_CDR_Encaps_Codec::operator= ( const TAO_CDR_Encaps_Codec  )  [private]

Member Data Documentation

Char codeset translator.

Definition at line 114 of file CDR_Encaps_Codec.h.

The major GIOP version associated with this Codec.

Definition at line 104 of file CDR_Encaps_Codec.h.

The minor GIOP version associated with this Codec.

Definition at line 107 of file CDR_Encaps_Codec.h.

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

Reimplemented from CORBA::Object.

Definition at line 111 of file CDR_Encaps_Codec.h.

WChar codeset translator.

Definition at line 117 of file CDR_Encaps_Codec.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines