operation_ss.cpp

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

CPP
751
字号
      // causing any problems.
      // Generate the return type mapping (same as in the header file)
      ctx = *this->ctx_;
      be_visitor_operation_rettype oro_visitor (&ctx);

      if (bt->accept (&oro_visitor) == -1)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "(%N:%l) be_visitor_operation_cs::"
                             "visit_operation - "
                             "codegen for return type failed\n"),
                            -1);
        }

      if (bt->size_type () == AST_Type::VARIABLE
          || bt->node_type () == AST_Decl::NT_array)
        {
          *os << " _tao_retval_info = _tao_retval._retn ();" << be_nl
              << "_tao_ri.result (_tao_retval_info);" << be_nl
              << "_tao_retval = _tao_retval_info;" << be_nl;
        }
      else
        {
          *os << " _tao_retval_info = _tao_retval;" << be_nl
              << "_tao_ri.result (_tao_retval_info);" << be_nl;
        }
    }

  *os << "_tao_ri.reply_status (PortableInterceptor::SUCCESSFUL);" << be_nl
      << "_tao_vfr.send_reply (&_tao_ri ACE_ENV_ARG_PARAMETER);"<< be_nl
          << "ACE_TRY_CHECK;" << be_uidt_nl;

  // Close scope of the "if (!_tao_vfr.location_forwarded()"
  // conditional block.
  *os << be_uidt << "}" << be_uidt_nl;

  *os << "}" << be_uidt_nl
      << "ACE_CATCHANY" << be_idt_nl
      << "{" << be_idt_nl;
  // Update the ServerRequestInfo exception attribute.
  *os << "_tao_ri.exception (&ACE_ANY_EXCEPTION);"<< be_nl
      << "_tao_vfr.send_exception (" << be_idt << be_idt_nl
      << "&_tao_ri" << be_nl
      << "ACE_ENV_ARG_PARAMETER" << be_uidt_nl
      << ");" << be_uidt_nl
      << "ACE_TRY_CHECK;" << be_nl;

  // The send_exception() interception point may have transformed the
  // caught exception.  In that event, we must not re-throw the caught
  // exception.
  *os << be_nl
      << "PortableInterceptor::ReplyStatus _tao_status =" << be_idt_nl
      << "_tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER);" << be_uidt_nl
      << "ACE_TRY_CHECK;" << be_nl;

  *os << be_nl
      << "if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION" << be_nl
      << "    || _tao_status == PortableInterceptor::USER_EXCEPTION)"
      << be_idt_nl
      << "{" << be_idt_nl;

  if (be_global->use_raw_throw ())
    {
      *os << "throw;";
    }
  else
    {
      *os << "ACE_RE_THROW;";
    }

  *os << be_uidt_nl
      << "}" << be_uidt << be_uidt_nl
      << "}" << be_uidt_nl;

  // Convert non-CORBA C++ exceptions to CORBA::UNKNOWN.
  *os << "\n# if defined (ACE_HAS_EXCEPTIONS) \\\n"
      << "  && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS)" << be_nl
      << "ACE_CATCHALL" << be_idt_nl
      << "{" << be_idt_nl
      << "CORBA::UNKNOWN ex;" << be_nl
      << be_nl
      << "_tao_ri.exception (&ex);"<< be_nl
      << "_tao_vfr.send_exception (" << be_idt << be_idt_nl
      << "&_tao_ri" << be_nl
      << "ACE_ENV_ARG_PARAMETER" << be_uidt_nl
      << ");" << be_uidt_nl
      << "ACE_TRY_CHECK;" << be_nl;

  // The receive_exception() interception point may have thrown a
  // PortableInterceptor::ForwardRequest exception.  In that event,
  // the connection retry loop must be restarted so do not throw the
  // CORBA::UNKNOWN exception to convert the unhandled C++ exception.
  *os << be_nl
      << "PortableInterceptor::ReplyStatus _tao_status =" << be_idt_nl
      << "_tao_ri.reply_status (ACE_ENV_SINGLE_ARG_PARAMETER);" << be_uidt_nl
      << "ACE_TRY_CHECK;" << be_nl;

  *os << be_nl
      << "if (_tao_status == PortableInterceptor::SYSTEM_EXCEPTION)"
      << be_idt_nl;

  if (be_global->use_raw_throw ())
    {
      *os << "throw ";
    }
  else
    {
      *os << "ACE_TRY_THROW ";
    }

  *os << "(ex);"  << be_uidt << be_uidt_nl
      << "}" << be_uidt
      << "\n# endif  /* ACE_HAS_EXCEPTIONS"
      << " && ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS */" << be_nl;

  *os << "ACE_ENDTRY;" << be_nl;
  *os << "ACE_CHECK;"
      << "\n#endif /* TAO_HAS_INTERCEPTORS */" << be_nl << be_nl;

  // Check if we are oneway in which case, we are done.
  if (node->flags () == AST_Operation::OP_oneway)
    {
      // We are done. Nothing else to do, except closing the function body.
      *os << "if (_tao_server_request.response_expected ()" << be_idt
          << be_idt_nl
          << "&& !_tao_server_request.sync_with_server ())" << be_uidt_nl
          << "{" << be_idt_nl
          << "_tao_server_request.init_reply ();" << be_uidt_nl
          << "}" << be_uidt;
    }

  // Marshal outgoing parameters.
  else if (this->gen_marshal_params (node, bt) == -1)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_visitor_operation_ss::"
                         "visit_operation - "
                         "gen_marshal_params failed\n"),
                        -1);
    }

  *os << be_nl << be_nl 
      << "// In case _tao_servant_upcall is not used in this function"
      << be_nl
      << "ACE_UNUSED_ARG (_tao_servant_upcall);" << be_uidt_nl
      << "}";;

  return 0;
}

int
be_visitor_operation_ss::visit_argument (be_argument *node)
{
  // This method is used to generate the ParamData table entry.

  TAO_OutStream *os = this->ctx_->stream ();

  // Retrieve the type for this argument.
  be_type *bt = be_type::narrow_from_decl (node->field_type ());

  if (!bt)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_visitor_operation_ss::"
                         "visit_argument - "
                         "Bad argument type\n"),
                        -1);
    }

  os->indent ();
  *os << "{" << bt->tc_name () << ", ";
  switch (node->direction ())
    {
    case AST_Argument::dir_IN:
      *os << "CORBA::ARG_IN, ";
      break;
    case AST_Argument::dir_INOUT:
      *os << "CORBA::ARG_INOUT, ";
      break;
    case AST_Argument::dir_OUT:
      *os << "CORBA::ARG_OUT, ";
      break;
    }
  *os << "0}";

  return 0;
}

int
be_visitor_operation_ss::gen_pre_skel_info (be_operation *node)
{
  TAO_OutStream *os = this->ctx_->stream ();

  // Now make sure that we have some in and inout parameters. Otherwise, there
  // is nothing to be marshaled in.
  if (this->has_param_type (node, AST_Argument::dir_IN) ||
      this->has_param_type (node, AST_Argument::dir_INOUT))
    {
      // Instantiate a TAO_InputCDR variable.
      os->indent ();
      *os << "TAO_InputCDR &_tao_in = _tao_server_request.incoming ();\n";
    }

  return 0;
}

int
be_visitor_operation_ss::gen_demarshal_params (be_operation *node,
                                               be_type *)
{
  TAO_OutStream *os = this->ctx_->stream ();
  be_visitor_context ctx;

  // Now make sure that we have some in and inout parameters. Otherwise, there
  // is nothing to be marshaled in.
  if (this->has_param_type (node, AST_Argument::dir_IN) ||
      this->has_param_type (node, AST_Argument::dir_INOUT))
    {
      // demarshal the in and inout arguments
      *os << be_nl << be_nl << "if (!(" << be_idt << be_idt;

      // Marshal each in and inout argument.
      ctx = *this->ctx_;
      ctx.state (TAO_CodeGen::TAO_OPERATION_ARG_DEMARSHAL_SS);
      ctx.sub_state (TAO_CodeGen::TAO_CDR_INPUT);
      be_visitor_operation_argument_marshal oad_visitor (&ctx);

      if (node->accept (&oad_visitor) == -1)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "(%N:%l) be_visitor_operation_ss::"
                             "gen_demarshal_params - "
                             "codegen for demarshal failed\n"),
                            -1);
        }

      *os << be_nl << "))" << be_uidt_nl;

      // If marshaling fails, raise exception (codesetting has minor codes)
      *os << "{" << be_idt_nl
          << "TAO_InputCDR::throw_skel_exception "
          << "(errno ACE_ENV_ARG_PARAMETER);"
          << be_nl
          << "ACE_CHECK;" << be_uidt_nl
          << "}" << be_uidt;
    };

  return 0;
}

int
be_visitor_operation_ss::gen_marshal_params (be_operation *node,
                                             be_type *bt)
{
  TAO_OutStream *os = this->ctx_->stream ();
  be_visitor_context ctx;

  // Setup parameters for marshaling and marshal them into the
  // outgoing stream.
  // The code below this is for 2way operations only.

  // We will be here only if we are 2way
  // first initialize a reply message
  *os << "_tao_server_request.init_reply ();";

  // We still need the following check because we maybe 2way and yet have no
  // parameters and a void return type.
  if (this->void_return_type (bt)
      && !this->has_param_type (node, AST_Argument::dir_INOUT)
      && !this->has_param_type (node, AST_Argument::dir_OUT))
    {
      return 0;
    }

  // Create temporary variables for the out and return parameters.
  if (!this->void_return_type (bt))
    {
      ctx = *this->ctx_;

      be_visitor_operation_rettype_post_upcall_ss visitor (&ctx);

      if (bt->accept (&visitor) == -1)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "(%N:%l) be_visitor_operation_ss::"
                             "gen_marshal_params - "
                             "codegen for return var [post upcall] failed\n"),
                            -1);
        }
    }

  // Generate any temporary variables to demarshal the arguments.
  ctx = *this->ctx_;
  be_visitor_args_post_upcall_ss vis1 (&ctx);

  if (node->accept (&vis1) == -1)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_visitor_operation_cs::"
                         "gen_pre_stub_info - "
                         "codegen for pre args failed\n"),
                        -1);
    }

  // Skip marshalling on location forward
  *os << "\n#if (TAO_HAS_INTERCEPTORS == 1)" << be_nl
      << "if (!_tao_vfr.location_forwarded ())" << be_idt_nl
      << "{" << be_idt;
  *os << "\n#endif /* TAO_HAS_INTERCEPTORS */"<< be_nl;

  *os << "TAO_OutputCDR &_tao_out = _tao_server_request.outgoing ();"
      << be_nl << be_nl;

  *os << "if (!(" << be_idt << be_idt;

  if (!this->void_return_type (bt))
    {
      // Demarshal the return val and each inout and out argument.
      ctx = *this->ctx_;
      ctx.sub_state (TAO_CodeGen::TAO_CDR_OUTPUT);
      be_visitor_operation_rettype_marshal_ss orm_visitor (&ctx);

      if (node->accept (&orm_visitor) == -1)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "(%N:%l) be_visitor_operation_ss::"
                             "gen_marshal_params - "
                             "codegen for return var failed\n"),
                            -1);
        }
    }

  if (this->has_param_type (node, AST_Argument::dir_INOUT)
      || this->has_param_type (node, AST_Argument::dir_OUT))
    {
      if (!this->void_return_type (bt))
        {
          // We have already printed the return val. SO put a &&.
          *os << " &&";
        }

      // Marshal each in and inout argument.
      ctx = *this->ctx_;
      ctx.state (TAO_CodeGen::TAO_OPERATION_ARG_MARSHAL_SS);
      ctx.sub_state (TAO_CodeGen::TAO_CDR_OUTPUT);
      be_visitor_operation_argument_marshal oam_visitor (&ctx);

      if (node->accept (&oam_visitor) == -1)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "(%N:%l) be_visitor_operation_ss::"
                             "gen_marshal_params - "
                             "codegen for args failed\n"),
                            -1);
        }
    }

  *os << be_nl << "))" << be_uidt_nl;

  // If marshaling fails, raise exception (codesetting has minor codes)
  *os << "{" << be_idt_nl
      << "TAO_OutputCDR::throw_skel_exception (errno ACE_ENV_ARG_PARAMETER);"
      << be_nl
      << "ACE_CHECK;" << be_uidt_nl
      << "}" << be_uidt;

  // End of scope: Skip marshalling on location forward
  *os << "\n#if (TAO_HAS_INTERCEPTORS == 1)"
      << be_uidt_nl << "}" << be_uidt;
  *os << "\n#endif /* TAO_HAS_INTERCEPTORS */" << be_nl;

  return 0;
}

⌨️ 快捷键说明

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