be_visitor_ami_pre_proc.cpp

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

CPP
1,431
字号
//
// be_visitor_ami_pre_proc.cpp,v 1.40 2003/12/23 15:48:41 bala Exp
//

/* -*- c++ -*- */
// ============================================================================
//
// = LIBRARY
//    TAO IDL
//
// = FILENAME
//    be_visitor_ami_pre_proc.cpp
//
// = DESCRIPTION
//    This visitor creates for AMI implied IDL constructs
//    the appropriate AST (Abstract Syntax Tree) node,
//    sets the corresponding interface or operation strategy
//    on it and enteres the nodes into the AST.
//
// = AUTHOR
//    Michael Kircher <Michael.Kircher@mchp.siemens.de>
//
// ============================================================================

#include "be_visitor_ami_pre_proc.h"
#include "be_visitor_context.h"
#include "be_root.h"
#include "be_module.h"
#include "be_interface.h"
#include "be_interface_strategy.h"
#include "be_valuetype.h"
#include "be_operation.h"
#include "be_operation_strategy.h"
#include "be_attribute.h"
#include "be_predefined_type.h"
#include "be_argument.h"
#include "utl_identifier.h"
#include "nr_extern.h"
#include "ace/Log_Msg.h"

ACE_RCSID (be, 
           be_visitor_ami_pre_proc, 
           "be_visitor_ami_pre_proc.cpp,v 1.40 2003/12/23 15:48:41 bala Exp")


be_visitor_ami_pre_proc::be_visitor_ami_pre_proc (be_visitor_context *ctx)
  : be_visitor_scope (ctx)
{

}

be_visitor_ami_pre_proc::~be_visitor_ami_pre_proc (void)
{

}

int
be_visitor_ami_pre_proc::visit_root (be_root *node)
{
  if (this->visit_scope (node) == -1)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_visitor_ami_pre_proc::"
                         "visit_root - "
                         "visit scope failed\n"),
                        -1);
    }

  return 0;
}

int
be_visitor_ami_pre_proc::visit_module (be_module *node)
{
  if (this->visit_scope (node) == -1)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_visitor_ami_pre_proc::"
                         "visit_module - "
                         "visit scope failed\n"),
                        -1);
    }

  return 0;
}

int
be_visitor_ami_pre_proc::visit_interface (be_interface *node)
{
  // We check for an imported node after generating the reply handler.
  if (node->is_local () || node->is_abstract ())
    {
      return 0;
    }

  AST_Module *module =
    AST_Module::narrow_from_scope (node->defined_in ());

  if (!module)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_visitor_ami_pre_proc::"
                         "visit_interface - "
                         "module is null\n"),
                        -1);
    }

  be_valuetype *excep_holder = 0;
  
  if (! node->imported ())
    {
      excep_holder = this->create_exception_holder (node);
    }

  be_interface *reply_handler = this->create_reply_handler (node,
                                                            excep_holder);
  if (reply_handler)
    {
      reply_handler->set_defined_in (node->defined_in ());

      // Insert the ami handler after the node, the
      // exception holder will be placed between these two later.
      module->be_add_interface (reply_handler, node);

      // Remember from whom we were cloned
      reply_handler->original_interface (node);

      // If this was created for an imported node, it will be wrong
      // unless we set it.
      reply_handler->set_imported (node->imported ());
    }
  else
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_visitor_ami_pre_proc::"
                         "visit_interface - "
                         "creating the reply handler failed\n"),
                        -1);
    }

  // After generating the reply handler for imported nodes, so they
  // can be looked up as possible parents of a reply handler from
  // a non-imported node, we can skip the rest of the function.
  if (node->imported ())
    {
      return 0;
    }

  // Set the proper strategy.
  be_interface_ami_strategy *bias = 0;
  ACE_NEW_RETURN (bias,
                  be_interface_ami_strategy (node,
                                             reply_handler),
                  -1);
  be_interface_strategy *old_strategy = node->set_strategy (bias);

  if (old_strategy)
    {
      delete old_strategy;
      old_strategy = 0;
    }

  if (excep_holder)
    {
      excep_holder->set_defined_in (node->defined_in ());
      // Insert the exception holder after the original node,
      // this way we ensure that it is *before* the
      // ami handler, which is the way we want to have it.
      module->be_add_interface (excep_holder, node);
      module->set_has_nested_valuetype ();
      // Remember from whom we were cloned.
      excep_holder->original_interface (node);

      // Set the strategy.
      be_interface_ami_exception_holder_strategy *biaehs = 0;
      ACE_NEW_RETURN (biaehs,
                      be_interface_ami_exception_holder_strategy (
                          excep_holder
                        ),
                      -1);

      be_interface_strategy *old_strategy =
        excep_holder->set_strategy (biaehs);

      if (old_strategy)
        {
          delete old_strategy;
          old_strategy = 0;
        }
    }
  else
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_visitor_ami_pre_proc::"
                         "visit_interface - "
                         "creating the exception holder failed\n"),
                        -1);
    }


  if (this->visit_scope (node) == -1)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_visitor_ami_pre_proc::"
                         "visit_interface - "
                         "visit scope failed\n"),
                        -1);
    }

  return 0;
}

int
be_visitor_ami_pre_proc::visit_operation (be_operation *node)
{
  if (node->flags () == AST_Operation::OP_oneway)
    {
      // We do nothing for oneways!
      return 0;
    }

  be_operation *sendc_marshaling =
    this->create_sendc_operation (node,
                                  0); // for arguments = FALSE

  be_operation *sendc_arguments =
    this->create_sendc_operation (node,
                                  1); // for arguments = TRUE

  if (sendc_marshaling && sendc_arguments)
    {
      sendc_marshaling->set_defined_in (node->defined_in ());

      sendc_arguments->set_defined_in (node->defined_in ());

      // We do not copy the exceptions because the exceptions
      // are delivered by the excep methods.

      // Set the proper strategy, and store the specialized
      // marshaling and arguments operations in it.
      be_operation_ami_sendc_strategy * boass = 0;
      ACE_NEW_RETURN (boass,
                      be_operation_ami_sendc_strategy (node,
                                                       sendc_marshaling,
                                                       sendc_arguments),
                      -1);

      be_operation_strategy *old_strategy = node->set_strategy (boass);

      if (old_strategy)
        {
          delete old_strategy;
          old_strategy = 0;
        }
    }

  return 0;
}

int
be_visitor_ami_pre_proc::visit_attribute (be_attribute *node)
{
  // Temporerily generate the set operation.
  be_operation *set_operation =
    this->generate_set_operation (node);

  this->visit_operation (set_operation);

  // Retrieve the strategy set by the visit operation.
  be_operation_default_strategy *bods = 0;
  ACE_NEW_RETURN (bods,
                  be_operation_default_strategy (set_operation),
                  -1);

  be_operation_strategy *set_operation_strategy =
    set_operation->set_strategy (bods);

  // Assign it to the attribute as set_operation strategy.
  if (set_operation_strategy)
    {
      be_operation_strategy *bos =
        node->set_set_strategy (set_operation_strategy);
      delete bos;
      bos = 0;
    }

  // Temporerily generate the get operation.
  be_operation *get_operation =
    this->generate_get_operation (node);

  this->visit_operation (get_operation);

  ACE_NEW_RETURN (bods,
                  be_operation_default_strategy (get_operation),
                  -1);

  be_operation_strategy *get_operation_strategy =
    get_operation->set_strategy (bods);

  if (get_operation_strategy)
    {
      be_operation_strategy *bos =
        node->set_get_strategy (get_operation_strategy);
      delete bos;
      bos = 0;
    }

  return 0;
}

be_valuetype *
be_visitor_ami_pre_proc::create_exception_holder (be_interface *node)
{
  Identifier *id = 0;
  ACE_NEW_RETURN (id,
                  Identifier ("Messaging"),
                  0);

  // Create a virtual module named "Messaging" and an valuetype "ExceptionHolder"
  // from which we inherit.
  UTL_ScopedName *inherit_name = 0;
  ACE_NEW_RETURN (inherit_name,
                  UTL_ScopedName (id,
                                  0),
                  0);

  ACE_NEW_RETURN (id,
                  Identifier ("ExceptionHolder"),
                  0);

  UTL_ScopedName *sn = 0;
  ACE_NEW_RETURN (sn,
                  UTL_ScopedName (id,
                                  0),
                  0);

  inherit_name->nconc (sn);

  be_valuetype *inherit_vt = 0;
  ACE_NEW_RETURN (inherit_vt,
                  be_valuetype (inherit_name,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0),
                  0);

  inherit_vt->set_name (inherit_name);

  ACE_NEW_RETURN (id,
                  Identifier ("Messaging"),
                  0);

  ACE_NEW_RETURN (sn,
                  UTL_ScopedName (id,
                                  0),
                  0);

  be_module *msg = 0;
  ACE_NEW_RETURN (msg,
                  be_module (sn),
                  0);

  // Notice the valuetype "ExceptionHolder" that it is defined in the
  // "Messaging" module
  inherit_vt->set_defined_in (msg);

  // Create the excpetion holder name
  ACE_CString excep_holder_local_name;
  this->generate_name (excep_holder_local_name,
                       "AMI_",
                       node->name ()->last_component ()->get_string(),
                       "ExceptionHolder");

  UTL_ScopedName *excep_holder_name =
    ACE_static_cast (UTL_ScopedName *, node->name ()->copy ());
  excep_holder_name->last_component ()->replace_string (
                                            excep_holder_local_name.rep ()
                                          );

  AST_Interface_ptr *p_intf = 0;
  ACE_NEW_RETURN (p_intf,
                  AST_Interface_ptr[1],
                  0);

  p_intf[0] = inherit_vt;

  be_valuetype *excep_holder = 0;
  ACE_NEW_RETURN (excep_holder,
                  be_valuetype (0,
                                p_intf,
                                1,
                                inherit_vt,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0),
                  0);

  excep_holder->set_name (excep_holder_name);
  excep_holder->seen_in_operation (I_TRUE);

  // Now our customized valuetype is created, we have to
  // add now the operations and attributes to the scope.

  if (node->nmembers () > 0)
    {
      // initialize an iterator to iterate thru our scope
      for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls);
           !si.is_done ();
           si.next ())
        {
          AST_Decl *d = si.item ();

          if (d == 0)
            {
              ACE_ERROR_RETURN ((LM_ERROR,
                                 "(%N:%l) be_visitor_ami_pre_proc::visit_interface - "
                                 "bad node in this scope\n"),
                                0);

            }

          be_decl *op = be_decl::narrow_from_decl (d);
          AST_Decl::NodeType nt = d->node_type ();

          if (nt == AST_Decl::NT_attr)
            {
              AST_Attribute *attribute = AST_Attribute::narrow_from_decl (d);

              if (!attribute)
                {
                  return 0;
                }

              this->create_raise_operation (op,
                                            excep_holder,
                                            GET_OPERATION);

              if (!attribute->readonly ())
                {
                  this->create_raise_operation (op,
                                                excep_holder,
                                                SET_OPERATION);
                }

            }
          else if (nt == AST_Decl::NT_op)
            {
              this->create_raise_operation (op,
                                            excep_holder,
                                            NORMAL);
            }
          else
            {
              continue;
            }
        } // end of while loop
    } // end of if

  return excep_holder;
}

be_interface *
be_visitor_ami_pre_proc::create_reply_handler (be_interface *node,
                                               be_valuetype *excep_holder)

⌨️ 快捷键说明

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