📄 be_interface.cpp
字号:
<< "ACE_INLINE void" << be_nl
<< (direct ? derived->full_direct_proxy_impl_name ()
: derived->full_thru_poa_proxy_impl_name ())
<< "::" << prefix << d->local_name () << " (" << be_idt << be_idt_nl
<< "TAO_Abstract_ServantBase *servant," << be_nl
<< "TAO::Argument ** args," << be_nl
<< "int num_args" << be_nl
<< "ACE_ENV_ARG_DECL" << be_uidt_nl
<< ")";
be_interface::gen_throw_spec (list, os);
*os << be_uidt_nl
<< "{" << be_idt_nl
<< (direct ? ancestor->full_direct_proxy_impl_name ()
: ancestor->full_thru_poa_proxy_impl_name ())
<< "::" << prefix << d->local_name () << " (" << be_idt << be_idt_nl
<< "servant," << be_nl
<< "args," << be_nl
<< "num_args" << be_nl
<< "ACE_ENV_ARG_PARAMETER" << be_uidt_nl
<< ");" << be_uidt << be_uidt_nl
<< "}"<< be_nl;
}
void
be_interface::analyze_parentage (void)
{
this->has_mixed_parentage_ = 0;
for (long i = 0; i < this->pd_n_inherits; ++i)
{
if (this->pd_inherits[i]->is_abstract ())
{
this->has_mixed_parentage_ = 1;
break;
}
}
if (this->has_mixed_parentage_ == 1)
{
be_global->mixed_parentage_interfaces.enqueue_tail (this);
}
}
// ****************************************************************
be_code_emitter_wrapper::
be_code_emitter_wrapper (be_interface::tao_code_emitter emitter)
: emitter_ (emitter)
{
}
int
be_code_emitter_wrapper::emit (be_interface *derived_interface,
TAO_OutStream *output_stream,
be_interface *base_interface)
{
return this->emitter_ (derived_interface,
base_interface,
output_stream);
}
// Template method that traverses the inheritance graph in a breadth-first
// style. The actual work on each element in the inheritance graph is carried
// out by the function passed as argument.
int
be_interface::traverse_inheritance_graph (be_interface::tao_code_emitter gen,
TAO_OutStream *os,
idl_bool abstract_paths_only)
{
// Make sure the queues are empty.
this->insert_queue.reset ();
this->del_queue.reset ();
// Insert ourselves in the queue.
if (insert_queue.enqueue_tail (this) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_interface::traverse_inheritance_graph - "
"error generating entries\n"),
-1);
}
be_code_emitter_wrapper wrapper (gen);
return this->traverse_inheritance_graph (wrapper,
os,
abstract_paths_only);
}
int
be_interface::traverse_inheritance_graph (
TAO_IDL_Inheritance_Hierarchy_Worker &worker,
TAO_OutStream *os,
idl_bool abstract_paths_only
)
{
AST_Interface *intf; // element inside the queue
if (!this->insert_queue.is_empty ())
{
// Dequeue the element at the head of the queue.
if (this->insert_queue.dequeue_head (intf))
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_interface::traverse_graph - "
"dequeue_head failed\n"),
-1);
}
// If we are doing a component, we check for a parent.
if (intf->node_type () == AST_Decl::NT_component)
{
AST_Component *base =
AST_Component::narrow_from_decl (intf)->base_component ();
if (base != 0)
{
(void) this->insert_non_dup (base);
long n_supports = base->n_supports ();
AST_Interface **supports = base->supports ();
for (long j = 0; j < n_supports; ++j)
{
(void) this->insert_non_dup (supports[j],
abstract_paths_only);
}
}
else
{
(void) this->insert_non_dup (be_global->ccmobject ());
}
}
(void) this->insert_non_dup (intf, abstract_paths_only);
}
// Do until queue is empty.
while (!this->insert_queue.is_empty ())
{
// Use breadth-first strategy i.e., first generate entries for ourselves,
// followed by nodes that we immediately inherit from, and so on. In the
// process make sure that we do not generate code for the same node more
// than once. Such a case may arise due to multiple inheritance forming
// a diamond-like inheritance graph.
// Dequeue the element at the head of the queue.
if (this->insert_queue.dequeue_head (intf))
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_interface::traverse_graph - "
"dequeue_head failed\n"),
-1);
}
// Insert the dequeued element in the del_queue.
if (this->del_queue.enqueue_tail (intf) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_interface::traverse_graph - "
"enqueue_head failed\n"),
-1);
}
be_interface *bi = be_interface::narrow_from_decl (intf);
// Use the helper method to generate code for ourself using the
// properties of the element dequeued. For the first iteration, the
// element dequeued and "this" will be the same i.e., ourselves.
if (worker.emit (this, os, bi) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%N:%l) be_interface::traverse_graph - "
"helper code gen failed\n"),
-1);
}
} // end of while queue not empty
return 0;
}
// Run GPERF and get the correct lookup and other operations
// depending on which strategy we are using. Returns 0 on sucess, -1
// on error.
int
be_interface::gen_gperf_things (const char *flat_name)
{
// GPERF can give Binary search, Linear search and Perfect Hash
// methods. Generate the class defintion according to that.
TAO_OutStream *os = this->strategy_->get_out_stream ();
*os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl
<< "// " << __FILE__ << ":" << __LINE__ << be_nl << be_nl;
// Generate the correct class definition for the operation lookup
// strategy. Then, get the lookup method from GPERF. And then,
// instantiate the correct class for the operation lookup strategy
// we are following.
switch (be_global->lookup_strategy ())
{
case BE_GlobalData::TAO_PERFECT_HASH:
// Output a class definition deriving from
// TAO_Perfect_Hash_OpTable.
this->gen_perfect_hash_class_definition (flat_name);
// Call GPERF and get the methods defined.
if (this->gen_gperf_lookup_methods (flat_name) == -1)
{
return -1;
}
// Create an instance of the correct class corresponding the
// operation lookup strategy we are following.
this->gen_perfect_hash_instance (flat_name);
break;
case BE_GlobalData::TAO_BINARY_SEARCH:
// Output a class definition deriving from
// TAO_Binary_Search_OpTable.
this->gen_binary_search_class_definition (flat_name);
// Call GPERF and get the methods defined.
if (gen_gperf_lookup_methods (flat_name) == -1)
{
return -1;
}
// Create an instance of the correct class corresponding the
// operation lookup strategy we are following.
this->gen_binary_search_instance (flat_name);
break;
case BE_GlobalData::TAO_LINEAR_SEARCH:
// Output a class definition deriving from
// TAO_Linear_Search_OpTable.
this->gen_linear_search_class_definition (flat_name);
// Call GPERF and get the methods defined.
if (this->gen_gperf_lookup_methods (flat_name) == -1)
{
return -1;
}
// Create an instance of the correct class corresponding the
// operation lookup strategy we are following.
this->gen_linear_search_instance (flat_name);
break;
default:
ACE_ERROR_RETURN ((
LM_ERROR,
"tao_idl:ERROR:%N:%l:Unknown Operation Lookup Strategy\n"
),
-1
);
}
return 0;
}
// Outputs the class definition for the perfect hashing. This class
// will inherit from the TAO_Perfect_Hash_OpTable.
void
be_interface::gen_perfect_hash_class_definition (const char *flat_name)
{
// Outstream.
TAO_OutStream *os = this->strategy_->get_out_stream ();
*os << "class " << "TAO_" << flat_name << "_Perfect_Hash_OpTable"
<< be_idt_nl
<< ": public TAO_Perfect_Hash_OpTable" << be_uidt_nl
<< "{" << be_nl
<< "private:" << be_idt_nl
<< "unsigned int hash (const char *str, unsigned int len);"
<< be_uidt_nl << be_nl
<< "public:" << be_idt_nl
<< "const TAO_operation_db_entry * lookup "
<< "(const char *str, unsigned int len);"
<< be_uidt_nl
<< "};\n\n";
}
// Outputs the class definition for the binary searching. This class
// will inherit from the TAO_Binary_Seach_OpTable.
void
be_interface::gen_binary_search_class_definition (const char *flat_name)
{
// Outstream.
TAO_OutStream *os = this->strategy_->get_out_stream ();
*os << "class " << "TAO_" << flat_name << "_Binary_Search_OpTable"
<< be_idt_nl
<< ": public TAO_Binary_Search_OpTable" << be_uidt_nl
<< "{" << be_nl
<< "public:" << be_idt_nl
<< "const TAO_operation_db_entry * lookup (const char *str);"
<< be_uidt_nl
<< "};\n\n";
}
// Outputs the class definition for the linear search. This class
// will inherit from the TAO_Linear_Search_OpTable.
void
be_interface::gen_linear_search_class_definition (const char *flat_name)
{
// Outstream.
TAO_OutStream *ss = this->strategy_->get_out_stream ();
*ss << "class " << "TAO_" << flat_name << "_Linear_Search_OpTable"
<< be_idt_nl
<< ": public TAO_Linear_Search_OpTable" << be_nl
<< "{" << be_nl
<< "public:" << be_idt_nl
<< "const TAO_operation_db_entry * lookup (const char *str);"
<< be_uidt_nl
<< "};\n\n";
}
// We have collected the input (Operations and the corresponding
// skeleton pointers) for the gperf program. Now let us execute gperf
// and get things done.
// GPERF reads from our temp file and write to the Server Skeleton
// file.
int
be_interface::gen_gperf_lookup_methods (const char *flat_name)
{
// Using ACE_Process.
ACE_Process process;
ACE_Process_Options process_options;
// Adjust the offset of the underlying file pointer.
ACE_OS::rewind (tao_cg->gperf_input_stream ()->file ());
// Set the stdin and stdout appropriately for the gperf program.
// Stdin is our temp file. Close the temp file and open. We will use
// <open_temp_file> to open the file now, so that the file will get
// deleted once when we close the file.
// Close the file.
if (ACE_OS::fclose (tao_cg->gperf_input_stream ()->file ()) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"%p:File close failed on temp gperf's input file\n",
"fclose"),
-1);
}
// Open the temp file.
ACE_HANDLE input = ACE::open_temp_file (tao_cg->gperf_input_filename (),
O_RDONLY);
if (input == ACE_INVALID_HANDLE)
{
ACE_ERROR_RETURN ((LM_ERROR,
"%p:File open failed on gperf's temp input file\n",
"open_temp_file"),
-1);
}
// Stdout is server skeleton. Do *not* close the file, just open
// again with <ACE_OS::open> with WRITE + APPEND option.. After
// this, remember to update the file offset to the correct location.
ACE_HANDLE output = ACE_OS::open (this->strategy_->get_out_stream_fname (),
O_WRONLY | O_APPEND);
if (output == ACE_INVALID_HANDLE)
{
ACE_OS::close (input);
ACE_ERROR_RETURN ((LM_ERROR,
"%p:File open failed on server skeleton file\n",
"open"),
-1);
}
// Seek to the end of the output file.
ACE_OS::lseek (output, 0, SEEK_END);
// Set the handles now in the process options.
process_options.set_handles (input, output);
int result = 0;
// Set the command line for the gperf program. Give the right
// arguments for the operation lookup strategy that we are using.
switch (be_global->lookup_strategy ())
{
// Perfect Hashing.
case BE_GlobalData::TAO_PERFECT_HASH:
process_options.command_line ("%s"
" "
"-m -M -J -c -C"
" "
"-D -E -T -f 0"
" "
"-F 0,0,0"
" "
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -