be_sequence.cpp

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

CPP
723
字号
// be_sequence.cpp,v 1.73 2003/10/29 02:58:07 bala Exp

// ============================================================================
//
// = LIBRARY
//    TAO IDL
//
// = FILENAME
//    be_sequence.cpp
//
// = DESCRIPTION
//    Extension of class AST_Sequence that provides additional means for C++
//    mapping.
//
// = AUTHOR
//    Copyright 1994-1995 by Sun Microsystems, Inc.
//    and
//    Aniruddha Gokhale
//
// ============================================================================

#include "be_sequence.h"
#include "be_typedef.h"
#include "be_interface.h"
#include "be_interface_fwd.h"
#include "be_predefined_type.h"
#include "be_field.h"
#include "be_visitor.h"
#include "be_helper.h"

#include "utl_identifier.h"
#include "idl_defines.h"
#include "nr_extern.h"
#include "global_extern.h"

#include "ace/Log_Msg.h"

ACE_RCSID (be,
           be_sequence,
           "be_sequence.cpp,v 1.73 2003/10/29 02:58:07 bala Exp")


be_sequence::be_sequence (void)
  : COMMON_Base (),
    AST_Decl (),
    AST_Type (),
    AST_ConcreteType (),
    AST_Sequence (),
    UTL_Scope (),
    be_scope (),
    be_decl (),
    be_type (),
    mt_ (be_sequence::MNG_UNKNOWN),
    field_node_ (0)
{
  // Always the case.
  this->has_constructor (I_TRUE);
}

be_sequence::be_sequence (AST_Expression *v,
                          AST_Type *t,
                          UTL_ScopedName *n,
                          idl_bool local,
                          idl_bool abstract)
  : COMMON_Base (t->is_local () || local,
                 abstract),
    AST_Decl (AST_Decl::NT_sequence,
              n,
              I_TRUE),
    AST_Type (AST_Decl::NT_sequence,
              n),
    AST_ConcreteType (AST_Decl::NT_sequence,
                      n),
    AST_Sequence (v,
                  t,
                  n,
                  t->is_local () || local,
                  abstract),
    UTL_Scope (AST_Decl::NT_sequence),
    be_scope (AST_Decl::NT_sequence),
    be_decl (AST_Decl::NT_sequence,
             n),
    be_type (AST_Decl::NT_sequence,
             n),
    mt_ (be_sequence::MNG_UNKNOWN),
    field_node_ (0)
{
  // Always the case.
  this->has_constructor (I_TRUE);

  // Don't want to set any bits below for imported nodes.
  if (this->imported ())
    {
      return;
    }

  // This one gets set for all sequences, in addition to any specialized
  // one that may get set below.
  ACE_SET_BITS (idl_global->decls_seen_info_,
                idl_global->decls_seen_masks.seq_seen_);

  // Don't need the return value - just set the member.
  (void) this->managed_type ();

  switch (this->mt_)
    {
      case MNG_OBJREF:
        ACE_SET_BITS (idl_global->decls_seen_info_,
                      idl_global->decls_seen_masks.iface_seq_seen_);
        break;
      case MNG_PSEUDO:
        ACE_SET_BITS (idl_global->decls_seen_info_,
                      idl_global->decls_seen_masks.pseudo_seq_seen_);
        break;
      case MNG_VALUE:
        ACE_SET_BITS (idl_global->decls_seen_info_,
                      idl_global->decls_seen_masks.vt_seq_seen_);
        break;
      case MNG_STRING:
        ACE_SET_BITS (idl_global->decls_seen_info_,
                      idl_global->decls_seen_masks.string_seq_seen_);
        break;
      case MNG_WSTRING:
        ACE_SET_BITS (idl_global->decls_seen_info_,
                      idl_global->decls_seen_masks.wstring_seq_seen_);
        break;
      default:
        break;
    }

  AST_Decl::NodeType nt = t->node_type ();
  AST_Typedef *td = 0;
  AST_Type *pbt = 0;

  if (nt == AST_Decl::NT_typedef)
    {
      td = AST_Typedef::narrow_from_decl (t);
      pbt = td->primitive_base_type ();
      nt = pbt->node_type ();
    }

  if (nt == AST_Decl::NT_pre_defined)
    {
      AST_PredefinedType *pdt = 
        AST_PredefinedType::narrow_from_decl (pbt ? pbt : t);

      switch (pdt->pt ())
        {
          case AST_PredefinedType::PT_octet:
            ACE_SET_BITS (idl_global->decls_seen_info_,
                          idl_global->decls_seen_masks.octet_seq_seen_);
            break;
          default:
            break;
        }
    }
}

// Helper to create_name.
char *
be_sequence::gen_name (void)
{
  char namebuf [NAMEBUFSIZE];
  be_type *bt = 0;

  // Reset the buffer.
  ACE_OS::memset (namebuf,
                  '\0',
                  NAMEBUFSIZE);

  // Retrieve the base type.
  bt = be_type::narrow_from_decl (this->base_type ());

  if (bt == 0)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%N:%l) be_sequence::"
                         "gen_name - "
                         "bad base type\n"),
                        0);
    }

  // If this is non-zero, add its local name to the generated name,
  // for uniqueness.
  be_field *fn = this->field_node_;

  if (bt->node_type () == AST_Decl::NT_sequence)
    {
      // Our base type is an anonymous sequence.
      be_sequence *seq = be_sequence::narrow_from_decl (bt);

      if (seq == 0)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "(%N:%l) be_sequence::"
                             "gen_name - "
                             "error converting base type to sequence\n"),
                            0);
        }

      // If the nested sequence were defined in
      // the scope of the enclosing sequence, we would have to
      // not only define the nested class in two places, but also
      // deal with the fact that, for the template classes, the
      // enclosing sequence's template type is a class defined
      // inside it. So we define the nested sequence in the next
      // scope up, and the existing code generation works for both
      // template and non-template implementations of IDL sequences.
      UTL_Scope *parent = this->defined_in ();
      seq->set_defined_in (parent);
      parent->add_sequence (seq);

      ACE_OS::sprintf (namebuf,
                       "_tao_seq_%s_%s",
                       seq->gen_name (),
                       fn ? fn->local_name ()->get_string () : "");
    }
  else
    {
      ACE_OS::sprintf (namebuf,
                       "_tao_seq_%s_",
                       bt->flat_name ());
    }

  // Append the size (if any).
  if (this->unbounded () == I_FALSE)
    {
      char ulval_str [NAMEBUFSIZE];
      ACE_OS::sprintf (ulval_str,
                       "_%lu",
                       this->max_size ()->ev ()->u.ulval);
      ACE_OS::strcat (namebuf,
                      ulval_str);
    }

  return ACE_OS::strdup (namebuf);
}

// Create a name for ourselves.
int
be_sequence::create_name (be_typedef *node)
{
  static char *namebuf = 0;
  UTL_ScopedName *n = 0;

  // Scope in which we are defined.
  be_decl *scope = 0;

  // If there is a typedef node, we use its name as our name.
  if (node)
    {
      this->set_name (node->name ());
    }
  else
    {
      // Generate a local name.
      namebuf = this->gen_name ();

      // Now see if we have a fully scoped name and if so, generate one.
      UTL_Scope *us = this->defined_in ();

      scope = be_scope::narrow_from_scope (us)->decl ();

      if (scope != 0)
        {
          // Make a copy of the enclosing scope's name.
          n = (UTL_ScopedName *) scope->name ()->copy ();

          Identifier *id = 0;
          ACE_NEW_RETURN (id,
                          Identifier (namebuf),
                          -1);

          UTL_ScopedName *conc_name = 0;
          ACE_NEW_RETURN (conc_name,
                          UTL_ScopedName (id,
                                          0),
                          -1);

          // Add our local name as the last component.
          n->nconc (conc_name);

          // Set the fully scoped name.
          this->set_name (n);
        }
      else
        {
          // We better be not here because we must be inside some scope,
          // at least the ROOT scope.
          return -1;
        }

      ACE_OS::free (namebuf);
    }

  return 0;
}

// Does this sequence have a managed type sequence element?
be_sequence::MANAGED_TYPE
be_sequence::managed_type (void)
{
  if (this->mt_ == be_sequence::MNG_UNKNOWN) // Not calculated yet.
    {
      // Base types.
      be_type *bt = 0;
      be_type *prim_type = 0;

      bt = be_type::narrow_from_decl (this->base_type ());

      if (bt->node_type () == AST_Decl::NT_typedef)
        {
          // Get the primitive base type of this typedef node.
          be_typedef *t = be_typedef::narrow_from_decl (bt);
          prim_type = t->primitive_base_type ();
        }
      else
        {
          prim_type = bt;
        }

      // Determine if we need a managed type and which one.
      switch (prim_type->node_type ())
        {
        case AST_Decl::NT_interface:
        case AST_Decl::NT_interface_fwd:
          this->mt_ = be_sequence::MNG_OBJREF;
          break;
        case AST_Decl::NT_valuetype:
        case AST_Decl::NT_valuetype_fwd:
          this->mt_ = be_sequence::MNG_VALUE;
          break;
        case AST_Decl::NT_string:
          this->mt_ = be_sequence::MNG_STRING;
          break;
        case AST_Decl::NT_wstring:
          this->mt_ = be_sequence::MNG_WSTRING;
          break;
        case AST_Decl::NT_pre_defined:
          {
            be_predefined_type *bpd =
              be_predefined_type::narrow_from_decl (prim_type);
            AST_PredefinedType::PredefinedType pt = bpd->pt ();

            switch (pt)
              {
                case AST_PredefinedType::PT_pseudo:
                  this->mt_ = be_sequence::MNG_PSEUDO;
                  break;
                case AST_PredefinedType::PT_object:
                  this->mt_ = be_sequence::MNG_PSEUDO;
                  break;
                case AST_PredefinedType::PT_value:
                  this->mt_ = be_sequence::MNG_VALUE;
                  break;
                default:
                  this->mt_ = be_sequence::MNG_NONE;
                  break;
              }
          }
          break;
        default:

⌨️ 快捷键说明

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