typecodefactory_i.cpp

来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 1,728 行 · 第 1/4 页

CPP
1,728
字号
// TypeCodeFactory_i.cpp,v 1.22 2003/12/04 20:20:06 parsons Exp

#include "TypeCodeFactory_i.h"

#include "tao/IFR_Client/IFR_BasicC.h"
#include "tao/Marshal.h"
#include "tao/ORB_Constants.h"

#include "ace/Containers_T.h"
#include "ace/Hash_Map_Manager_T.h"
#include "ace/Null_Mutex.h"

ACE_RCSID (TypeCodeFactory,
           TypeCodeFactory_i,
           "TypeCodeFactory_i.cpp,v 1.22 2003/12/04 20:20:06 parsons Exp")

TAO_TypeCodeFactory_i::TAO_TypeCodeFactory_i (void)
{
}

TAO_TypeCodeFactory_i::~TAO_TypeCodeFactory_i (void)
{
}

TAO_TypeCodeFactory_i *
TAO_TypeCodeFactory_i::_narrow (CORBA::Object_ptr _tao_objref
                                ACE_ENV_ARG_DECL_NOT_USED)
{
  if (CORBA::is_nil (_tao_objref))
    {
      return 0;
    }

  return dynamic_cast<TAO_TypeCodeFactory_i *> (_tao_objref);
}

CORBA::TypeCode_ptr
TAO_TypeCodeFactory_i::create_struct_tc (
    const char *id,
    const char *name,
    const CORBA::StructMemberSeq &members
    ACE_ENV_ARG_DECL
  )
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return this->struct_except_tc_common (id,
                                        name,
                                        members,
                                        CORBA::tk_struct
                                        ACE_ENV_ARG_PARAMETER);
}

CORBA::TypeCode_ptr
TAO_TypeCodeFactory_i::create_union_tc (
    const char *id,
    const char *name,
    CORBA::TypeCode_ptr discriminator_type,
    const CORBA::UnionMemberSeq &members
    ACE_ENV_ARG_DECL
  )
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  if (name != 0 && !this->valid_name (name))
    {
      ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 15,
                                          CORBA::COMPLETED_NO),
                        CORBA::TypeCode::_nil ());
    }

  if (id != 0 && !this->valid_id (id))
    {
      ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 16,
                                          CORBA::COMPLETED_NO),
                        CORBA::TypeCode::_nil ());
    }

  CORBA::Boolean good_disc_type =
    this->valid_disc_type (discriminator_type
                           ACE_ENV_ARG_PARAMETER);
  ACE_CHECK_RETURN (CORBA::TypeCode::_nil ());

  if (!good_disc_type)
    {
      ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 20,
                                          CORBA::COMPLETED_NO),
                        CORBA::TypeCode::_nil ());
    }

  CORBA::ULong len = members.length ();
  CORBA::ULong dups = 0;
  CORBA::ULong raw_default_index = ACE_UINT32_MAX;
  CORBA::Long default_index = -1;
  CORBA::Octet value = ACE_OCTET_MAX;
  CORBA::TypeCode_ptr tc_holder = CORBA::TypeCode::_nil ();
  CORBA::Boolean valid_member = 1;
  const char *member_name = 0;
  ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map;

  // No getting around iterating over the members twice. We have
  // to do it once *before* the overall length is written to the
  // CDR stream, to know by how much, if any, the number of members
  // differs from the number of labels.
  for (CORBA::ULong i = 0; i < len; ++i)
    {
      member_name = members[i].name;
      int trybind_status = 0;

      if (i > 0)
        {
          // Is this a duplicate case label? If so, we have to adjust
          // the 'length' we encode - a member gets encoded only once.
          if (ACE_OS::strcmp (member_name,
                              members[i - 1].name)
               == 0)
            {
              CORBA::Boolean equiv =
                members[i].type.in ()->equivalent (members[i - 1].type.in ()
                                                   ACE_ENV_ARG_PARAMETER);
              ACE_CHECK_RETURN (CORBA::TypeCode::_nil ());

              // If adjacent names are the same and their types are equivalent,
              // then they are duplicate case labels. If the types are not
              // equivalent, then they are separate members with the same name,
              // which is not allowed.
              if (equiv)
                {
                  ++dups;
                }
              else
                {
                  ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 17,
                                                      CORBA::COMPLETED_NO),
                                    CORBA::TypeCode::_nil ());
                }
            }
          else
            {
              // Only if we do not have a duplicate case label do we
              // check for a duplicate member name.
              ACE_CString ext_id (member_name);
              int int_id = 0;

              trybind_status = map.trybind (ext_id, int_id);
            }
        }
      else
        {
          ACE_CString ext_id (member_name);
          int int_id = 0;

          trybind_status = map.trybind (ext_id, int_id);
        }

      // Duplicate member name?
      if (trybind_status != 0)
        {
          ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 17,
                                              CORBA::COMPLETED_NO),
                            CORBA::TypeCode::_nil ());
        }

      tc_holder = members[i].type.in ();

      // Valid member type?
      valid_member = this->valid_content_type (tc_holder
                                               ACE_ENV_ARG_PARAMETER);
      ACE_CHECK_RETURN (CORBA::TypeCode::_nil ());

      if (!valid_member)
        {
          ACE_THROW_RETURN (CORBA::BAD_TYPECODE (2,
                                                 CORBA::COMPLETED_NO),
                            CORBA::TypeCode::_nil ());
        }

      // Reset the default index, if we have a default case label.
      if ((members[i].label >>= CORBA::Any::to_octet (value)) == 1)
        {
          if (value == 0)
            {
              raw_default_index = i;
              // Only the multiple labels that come before the
              // default label affect its adjusted value.
              default_index = ACE_static_cast (CORBA::Long, i - dups);
            }
        }
      else
        {
          // Else check that the label type is equivalent to the
          // given discriminator type.
          CORBA::TypeCode_var tmp = members[i].label.type ();

          CORBA::Boolean equiv =
            discriminator_type->equivalent (tmp.in ()
                                            ACE_ENV_ARG_PARAMETER);
          ACE_CHECK_RETURN (CORBA::TypeCode::_nil ());

          if (!equiv)
            {
              ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 19,
                                                  CORBA::COMPLETED_NO),
                                CORBA::TypeCode::_nil ());
            }
        }
    }

  CORBA::Boolean unique_labels =
    this->unique_label_values (members,
                               discriminator_type,
                               raw_default_index
                               ACE_ENV_ARG_PARAMETER);
  ACE_CHECK_RETURN (CORBA::TypeCode::_nil ());

  if (!unique_labels)
    {
      ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 18,
                                          CORBA::COMPLETED_NO),
                        CORBA::TypeCode::_nil ());
    }

  TAO_OutputCDR cdr;
  CORBA::TypeCode::OFFSET_MAP *offset_map = 0;

  cdr << TAO_ENCAP_BYTE_ORDER;

  cdr << id;

  cdr << name;

  cdr << discriminator_type;

  cdr << default_index;

  cdr << len - dups;

  for (CORBA::ULong index = 0; index < len; ++index)
    {
      if (index > 0)
        {
          // Is this a duplicate case label? If so, skip it - a member
          // goes into the typecode only once.
          if (ACE_OS::strcmp (members[index].name,
                              members[index - 1].name)
               == 0)
            {
              continue;
            }
        }

      CORBA::TCKind kind = discriminator_type->kind (ACE_ENV_SINGLE_ARG_PARAMETER);

      if (index == raw_default_index)
        {
          // This is the default label - we have to find a legal value.
          this->compute_default_label (kind,
                                       index,
                                       members,
                                       cdr);
        }
      else
        {
          CORBA::Boolean good_label =
            this->insert_label_value (kind,
                                      members[index].label,
                                      cdr
                                      ACE_ENV_ARG_PARAMETER);
          ACE_CHECK_RETURN (CORBA::TypeCode::_nil ());

          if (good_label == 0)
            {
              return CORBA::TypeCode::_nil ();
            }
        }

      cdr << members[index].name;

      if (members[index].type->offset_map () != 0)
        {
          this->update_map (offset_map,
                            members[index].type.in (),
                            id,
                            cdr);
        }

      cdr << members[index].type.in ();
    }

  return this->assemble_tc (cdr,
                            CORBA::tk_union,
                            offset_map
                            ACE_ENV_ARG_PARAMETER);
}

CORBA::TypeCode_ptr
TAO_TypeCodeFactory_i::create_enum_tc (
    const char *id,
    const char *name,
    const CORBA::EnumMemberSeq &members
    ACE_ENV_ARG_DECL
  )
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  if (name != 0 && !this->valid_name (name))
    {
      ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 15,
                                          CORBA::COMPLETED_NO),
                        CORBA::TypeCode::_nil ());
    }

  if (id != 0 && !this->valid_id (id))
    {
      ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 16,
                                          CORBA::COMPLETED_NO),
                        CORBA::TypeCode::_nil ());
    }

  TAO_OutputCDR cdr;

  cdr << TAO_ENCAP_BYTE_ORDER;

  cdr << id;

  cdr << name;

  CORBA::ULong len = members.length ();

  cdr << len;

  ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map;

  for (CORBA::ULong index = 0; index < len; ++index)
    {
      ACE_CString ext_id (members[index]);
      int int_id = 0;

      // Is there a duplicate member name?
      if (map.trybind (ext_id, int_id) != 0)
        {
          ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 17,
                                              CORBA::COMPLETED_NO),
                            CORBA::TypeCode::_nil ());
        }

      cdr << members[index].in ();
    }

  return this->assemble_tc (cdr,
                            CORBA::tk_enum,
                            0
                            ACE_ENV_ARG_PARAMETER);
}

CORBA::TypeCode_ptr
TAO_TypeCodeFactory_i::create_alias_tc (
    const char *id,
    const char *name,
    CORBA::TypeCode_ptr original_type
    ACE_ENV_ARG_DECL
  )
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return this->alias_value_box_tc_common (id,
                                          name,
                                          original_type,
                                          CORBA::tk_alias
                                          ACE_ENV_ARG_PARAMETER);
}

CORBA::TypeCode_ptr
TAO_TypeCodeFactory_i::create_exception_tc (
    const char *id,
    const char *name,
    const CORBA::StructMemberSeq &members
    ACE_ENV_ARG_DECL
  )
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return this->struct_except_tc_common (id,
                                        name,
                                        members,
                                        CORBA::tk_except
                                        ACE_ENV_ARG_PARAMETER);
}

CORBA::TypeCode_ptr
TAO_TypeCodeFactory_i::create_interface_tc (
    const char *id,
    const char *name
    ACE_ENV_ARG_DECL
  )
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return this->create_tc_common (id,
                                 name,
                                 CORBA::tk_objref
                                 ACE_ENV_ARG_PARAMETER);
}

CORBA::TypeCode_ptr
TAO_TypeCodeFactory_i::create_string_tc (
    CORBA::ULong bound
    ACE_ENV_ARG_DECL
  )
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return this->string_wstring_tc_common (bound,
                                         CORBA::tk_string
                                         ACE_ENV_ARG_PARAMETER);
}

CORBA::TypeCode_ptr
TAO_TypeCodeFactory_i::create_wstring_tc (
    CORBA::ULong bound
    ACE_ENV_ARG_DECL
  )
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return this->string_wstring_tc_common (bound,
                                         CORBA::tk_wstring
                                         ACE_ENV_ARG_PARAMETER);
}

CORBA::TypeCode_ptr
TAO_TypeCodeFactory_i::create_fixed_tc (
    CORBA::UShort /* digits */,
    CORBA::UShort /* scale */
    ACE_ENV_ARG_DECL
  )
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (TAO_DEFAULT_MINOR_CODE,
                                         CORBA::COMPLETED_NO),

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?