⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ifr_adding_visitor_union.cpp

📁 这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用于网络游戏医学图像网关的高qos要求.更详细的内容可阅读相应的材料
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -*- c++ -*- */
// ifr_adding_visitor_union.cpp,v 1.17 2003/10/28 18:34:03 bala Exp

#include "ast_enum.h"
#include "ast_expression.h"
#include "ast_union.h"
#include "ast_union_branch.h"
#include "ast_union_label.h"
#include "utl_identifier.h"

#include "ifr_adding_visitor_union.h"
#include "ifr_adding_visitor_structure.h"

#include "tao/Any_Unknown_IDL_Type.h"

ACE_RCSID (IFR_Service,
           ifr_adding_visitor_union,
           "ifr_adding_visitor_union.cpp,v 1.17 2003/10/28 18:34:03 bala Exp")

ifr_adding_visitor_union::ifr_adding_visitor_union (
    AST_Decl *scope,
    CORBA::Boolean is_nested
  )
  : ifr_adding_visitor (scope),
    is_nested_ (is_nested)
{
}

ifr_adding_visitor_union::~ifr_adding_visitor_union (void)
{
}

// Specialized visit_scope method for unions only.
int
ifr_adding_visitor_union::visit_scope (UTL_Scope *node)
{
  // If the union has members that are scopes but not unions,
  // the regular visit_scope method should be called instead.
  if (node->scope_node_type () != AST_Decl::NT_union)
    {
      return ifr_adding_visitor::visit_scope (node);
    }

  AST_Union *u = AST_Union::narrow_from_scope (node);

  CORBA::ULong nfields = ACE_static_cast (CORBA::ULong,
                                          u->nfields ());

  this->members_.length (nfields);

  AST_Field **f = 0;

  // Index into members_.
  CORBA::ULong index = 0;

  ACE_DECLARE_NEW_CORBA_ENV;
  ACE_TRY
    {
      // Visit each field.
      for (CORBA::ULong i = 0; i < nfields; ++i)
        {
          if (u->field (f, i) != 0)
            {
              ACE_ERROR_RETURN ((
                  LM_ERROR,
                  ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
                  ACE_TEXT ("visit_scope -")
                  ACE_TEXT (" field node access failed\n")
                ),
                -1
              );
            }

          AST_Type *ft = (*f)->field_type ();

          idl_bool defined_here = ft->is_child (this->scope_);

          // If the union member is defined in the union, we have to
          // do some visiting - otherwise we can just look up the entry.
          if (defined_here)
            {
              if (ft->node_type () == AST_Decl::NT_union)
                {
                  // Since the enclosing scope hasn't been created yet,
                  // we make a special visitor to create this member
                  // at global scope and move it into the union later.
                  ifr_adding_visitor_union visitor (ft,
                                                    1);

                  if (ft->ast_accept (&visitor) == -1)
                    {
                      ACE_ERROR_RETURN ((
                          LM_ERROR,
                          ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
                          ACE_TEXT ("visit_scope -")
                          ACE_TEXT (" failed to accept visitor\n")
                        ),
                        -1
                      );
                    }

                  this->ir_current_ =
                    CORBA::IDLType::_duplicate (visitor.ir_current ());

                  CORBA::Contained_ptr tmp =
                    CORBA::Contained::_narrow (visitor.ir_current ()
                                              ACE_ENV_ARG_PARAMETER);
                  ACE_TRY_CHECK;

                  this->move_queue_.enqueue_tail (tmp);
                }
              else
                {
                  if (ft->ast_accept (this) == -1)
                    {
                      ACE_ERROR_RETURN ((
                          LM_ERROR,
                          ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
                          ACE_TEXT ("visit_scope -")
                          ACE_TEXT (" failed to accept visitor\n")
                        ),
                        -1
                      );
                    }
                }
            }
          else
            {
              // Updates ir_current_.
              this->get_referenced_type (ft
                                         ACE_ENV_ARG_PARAMETER);
              ACE_TRY_CHECK;
            }

          // Get the case label(s).

          AST_UnionBranch *ub = 0;
          AST_UnionLabel *case_label = 0;

          ub = AST_UnionBranch::narrow_from_decl (*f);

          unsigned long len = ub->label_list_length ();

          // If there are multiple case labels, we will have an element
          // in the UnionMemberSeq for each label, not just for each member,
          // so the list length and the loop terminator must both be
          // increased accordingly.
          if (len > 1)
            {
              this->members_.length (this->members_.length () + len - 1);
            }

          for (unsigned long j = 0; j < len; ++j)
            {
              case_label = ub->label (j);

              // Is this a regular label or default label?
              if (case_label->label_kind () == AST_UnionLabel::UL_label)
                {
                  AST_Expression::AST_ExprValue *ev =
                    case_label->label_val ()->ev ();

                  // If the discriminator is an enum, we can't just insert
                  // a ulong into the Any member of struct UnionMember.
                  if (u->disc_type ()->node_type () == AST_Decl::NT_enum)
                    {
                      TAO_OutputCDR cdr;
                      cdr.write_ulong (ev->u.ulval);
                      TAO::Unknown_IDL_Type *unk = 0;
                      ACE_NEW_RETURN (unk,
                                      TAO::Unknown_IDL_Type (
                                          this->disc_tc_.in (),
                                          cdr.begin (),
                                          TAO_ENCAP_BYTE_ORDER
                                        ),
                                      -1);
                      this->members_[index].label.replace (unk);
                    }
                  else
                    {
                      this->load_any (ev,
                                      this->members_[index].label);
                    }
                }
              else      // Default case label.
                {
                  this->members_[index].label <<= CORBA::Any::from_octet (0);
                }

              this->members_[index].name =
                CORBA::string_dup ((*f)->local_name ()->get_string ());

              // IfR method create_union does not use this - it just needs
              // to be non-zero for marshaling.
              this->members_[index].type =
                CORBA::TypeCode::_duplicate (CORBA::_tc_void);

              this->members_[index++].type_def =
                CORBA::IDLType::_duplicate (this->ir_current_.in ());
            }
        }
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION (
          ACE_ANY_EXCEPTION,
          ACE_TEXT ("ifr_adding_visitor_union::visit_scope")
        );

      return -1;
    }
  ACE_ENDTRY;

  return 0;
}

int
ifr_adding_visitor_union::visit_structure (AST_Structure *node)
{
  ACE_DECLARE_NEW_CORBA_ENV;
  ACE_TRY
    {
      // Is this struct already in the respository?
      CORBA::Contained_var prev_def =
        be_global->repository ()->lookup_id (node->repoID ()
                                             ACE_ENV_ARG_PARAMETER);
      ACE_TRY_CHECK;

      // If not, create a new entry.
      if (CORBA::is_nil (prev_def.in ()))
        {
          ifr_adding_visitor_structure visitor (node,
                                                1);

          int retval = visitor.visit_structure (node);

          if (retval == 0)
            {
              // Get the result of the visit.
              this->ir_current_ =
                CORBA::IDLType::_duplicate (visitor.ir_current ());

              CORBA::Contained_ptr tmp =
                CORBA::Contained::_narrow (visitor.ir_current ()
                                          ACE_ENV_ARG_PARAMETER);
              ACE_TRY_CHECK;

              // Since the enclosing UnionDef hasn't been created
              // yet, we don't have a scope, so this nested StructDef
              // (which was created at global scope) goes on the
              // queue to be moved later.
              this->move_queue_.enqueue_tail (tmp);
            }

          return retval;
        }
      else
        {
          // If the line below is true, we are clobbering a previous
          // entry (from another IDL file) of another type. In that
          // case we do what other ORB vendors do, and destroy the
          // original entry, create the new one, and let the user beware.
          if (node->ifr_added () == 0)
            {
              prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
              ACE_TRY_CHECK;

              // This call will take the other branch.
              return this->visit_structure (node);
            }

          this->ir_current_ =
            CORBA::IDLType::_narrow (prev_def.in ()
                                    ACE_ENV_ARG_PARAMETER);
          ACE_TRY_CHECK;
        }
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION (
          ACE_ANY_EXCEPTION,
          ACE_TEXT ("ifr_adding_visitor_union::visit_structure")
        );

⌨️ 快捷键说明

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