text: /*
   *                         Vortex OpenSplice
   *
   *   This software and documentation are Copyright 2006 to TO_YEAR ADLINK
   *   Technology Limited, its affiliated companies and licensors. All rights
   *   reserved.
   *
   *   Licensed under the Apache License, Version 2.0 (the "License");
   *   you may not use this file except in compliance with the License.
   *   You may obtain a copy of the License at
   *
   *       http://www.apache.org/licenses/LICENSE-2.0
   *
   *   Unless required by applicable law or agreed to in writing, software
   *   distributed under the License is distributed on an "AS IS" BASIS,
   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *   See the License for the specific language governing permissions and
   *   limitations under the License.
   *
   */
  #include "idl.h"
  #include "xbe_dispatchable.h"
  #include "xbe_literals.h"
  #include "xbe_utils.h"
  
  IMPL_NARROW_METHODS0 (be_DispatchableType)
  
  void be_DispatchableType::DeclareForDispatcher
  (
     ostream& os,
     be_Tab& tab,
     const be_CppName& implClassName,
     const be_CppName& argName,
     const be_ArgumentDirection& direction
  ) const
  {
     switch (direction)
     {
        case VT_InParam:
        {
           DeclareIn (os, tab, implClassName, argName);
        }
        break;
  
        case VT_OutParam:
        case VT_Return:
        {
           DeclareOutOrReturn (os, tab, argName, direction);
        }
        break;
  
        case VT_InOutParam:
        {
           DeclareInout (os, tab, implClassName, argName);
        }
        break;
  
        default:
        {
           assert (0);
        }
     }
  }
  
  void be_DispatchableType::DeclareIn
  (
     ostream& os,
     be_Tab& tab,
     const be_CppName& implClassName,
     const be_CppName& argName
  ) const
  {
     switch (HowStoredInDispatcher (VT_InParam))
     {
        case STORED_AS_STACK_VARIABLE:
        {
           os << tab << TypeName () << " " << argName << ";" << nl;
        }
        break;
  
        case STORED_IN_VAR:
        case STORED_IN_ALLOCED_VAR:
        case STORED_IN_DESCENDANT_VAR:
        case STORED_IN_STRING_VAR:
        {
           os << tab << TypeName () << DDSVarExtension << " " << argName << ";" << nl;
        }
        break;
  
        case STORED_IN_IOR_VAR:
        {
           DDSString stubFactory = BE_Globals::RelativeScope
           (
              DDSString (implClassName),
              Scope (localName)
           );
           os << tab << ScopedName () << DDSVarExtension << " " << argName
           << " (new " << stubFactory;
           // Add extension
           os << DDSStubExtension << " ());" << nl;
        }
        break;
  
        default:
        {
           assert (0);
        }
     }
  }
  
  void be_DispatchableType::DeclareOutOrReturn
  (
     ostream& os,
     be_Tab& tab,
     const be_CppName& argName,
     const be_ArgumentDirection& direction
  ) const
  {
     switch (HowStoredInDispatcher(direction))
     {
        case STORED_AS_STACK_VARIABLE:
        {
           os << tab << TypeName () << " " << argName << ";" << nl;
        }
        break;
  
        case STORED_IN_VAR:
        case STORED_IN_STRING_VAR:
        case STORED_IN_ALLOCED_VAR:
        case STORED_IN_DESCENDANT_VAR:
        case STORED_IN_IOR_VAR:
        {
           os << tab << TypeName () << DDSVarExtension << " " << argName << ";" << nl;
        }
        break;
  
        default:
        {
           assert(0);
        }
     }
  }
  
  void be_DispatchableType::DeclareInout
  (
     ostream& os,
     be_Tab& tab,
     const be_CppName& implClassName,
     const be_CppName& argName
  ) const
  {
     switch (HowStoredInDispatcher (VT_InOutParam))
     {
        case STORED_AS_STACK_VARIABLE:
        {
           os << tab << TypeName () << " " << argName << ";" << nl;
        }
        break;
  
        case STORED_IN_VAR:
        case STORED_IN_STRING_VAR:
        case STORED_IN_DESCENDANT_VAR:
        {
           os << tab << TypeName () << DDSVarExtension << " " << argName << ";" << nl;
        }
        break;
  
        case STORED_IN_ALLOCED_VAR:
        {
           DDSString relTypeName =
              BE_Globals::RelativeScope(DDSString(implClassName), typeName);
           os << tab << relTypeName << DDSVarExtension << " " << argName << " = "
           << relTypeName << "_alloc ();" << nl;
        }
        break;
  
        case STORED_IN_IOR_VAR:
        {
           DDSString stubFactory =
              BE_Globals::RelativeScope(DDSString(implClassName),
                                        Scope(localName) + "");
           os << tab << ScopedName() << DDSVarExtension << " " << argName
              << " (new " << stubFactory << DDSStubExtension << " ());" << nl;
        }
        break;
  
        default:
        {
           assert(0);
        }
     }
  }
  
  DDSString be_DispatchableType::PassToServantMethod
  (
     const be_CppName& argName,
     const be_ArgumentDirection& direction,
     int getargIndex
  ) const
  {
     DDSString result;
  
     switch (direction)
     {
        case VT_InParam:
        {
           result = PassInToServantMethod (argName, getargIndex);
        }
        break;
  
        case VT_OutParam:
        {
           result = PassOutToServantMethod (argName, getargIndex);
        }
        break;
  
        case VT_InOutParam:
        {
           result = PassInoutToServantMethod (argName, getargIndex);
        }
        break;
  
        case VT_Return:
        default:
        {
           assert(0);
        }
     }
  
     return result;
  }
  
  // extract the m_value pointer from _out_[], cast it to the type of this,
  // and dereference the pointer
  
  DDSString be_DispatchableType::DereferenceMvalue
     (int getargIndex) const
  {
     DDSString result = "*(";
     result += ScopedName ();
     result += (DDSString)"*)_out_[";
     result += getargIndex;
     result += "].m_value";
     return result;
  }
  
  DDSString be_DispatchableType::PassInToServantMethod
  (
     const be_CppName& argName,
     int getargIndex
  ) const
  {
     DDSString result;
  
     switch (HowStoredInDispatcher (VT_InParam))
     {
        case STORED_AS_STACK_VARIABLE:
        case STORED_IN_VAR:
        case STORED_IN_STRING_VAR:
        case STORED_IN_ALLOCED_VAR:
        {
           result = DereferenceMvalue (getargIndex);
        }
        break;
  
        case STORED_IN_DESCENDANT_VAR:
        {
           result += "*(";
           result += ScopedName();
           result += "**)_out_[";
           result += getargIndex;
           result += "].m_value";
        }
        break;
  
        case STORED_IN_IOR_VAR:
        {
           result = argName;
        }
        break;
  
        default:
        {
           assert(0);
        }
     }
  
     return result;
  }
  
  DDSString be_DispatchableType::PassOutToServantMethod
  (
     const be_CppName& argName,
     int getargIndex
  ) const
  {
     DDSString result;
  
     switch (HowStoredInDispatcher (VT_OutParam))
     {
        case STORED_AS_STACK_VARIABLE:
        case STORED_IN_VAR:
        case STORED_IN_STRING_VAR:
        case STORED_IN_ALLOCED_VAR:
        {
           result = argName;
        }
        break;
  
        case STORED_IN_DESCENDANT_VAR:
        case STORED_IN_IOR_VAR:
        {
           result = DDSString (argName) + DDSString (".out ()");
        }
        break;
  
        default:
        {
           assert(0);
        }
     }
  
     return result;
  }
  
  DDSString be_DispatchableType::PassInoutToServantMethod
  (
     const be_CppName& argName,
     int getargIndex
  ) const
  {
     DDSString result;
  
     switch (HowStoredInDispatcher (VT_InOutParam))
     {
        case STORED_AS_STACK_VARIABLE:
        case STORED_IN_VAR:
        case STORED_IN_STRING_VAR:
        case STORED_IN_ALLOCED_VAR:
        {
           result = DereferenceMvalue (getargIndex);
        }
        break;
  
        case STORED_IN_DESCENDANT_VAR:
        {
           result = "*(";
           result += ScopedName();
           result += "**&)_out_[";
           result += getargIndex;
           result += "].m_value";
        }
        break;
  
        case STORED_IN_IOR_VAR:
        {
           result = DDSString(argName) + DDSString(".inout()");
        }
        break;
  
        default:
        {
           assert(0);
        }
     }
  
     return result;
  }
  
  DDSString be_DispatchableType::GetargMvalue
  (
     const be_CppName & argName,
     const be_ArgumentDirection & direction
  ) const
  {
     DDSString result;
  
     switch (HowStoredInDispatcher (direction))
     {
        case STORED_AS_STACK_VARIABLE:
        {
           result = "&";
           result += argName;
           break;
        }
        case STORED_IN_VAR:
        case STORED_IN_STRING_VAR:
        case STORED_IN_DESCENDANT_VAR:
        {
           result = "&";
           result += DDSString(argName) + DDSString(".val ()");
           break;
        }
        case STORED_IN_ALLOCED_VAR:
        {
           result = DDSString (argName) + DDSString (".val ()");
           break;
        }
        case STORED_IN_IOR_VAR:
        {
           result = "&";
           result += DDSString (argName) + DDSString ("->get_ior ()");
           break;
        }
        default:
        {
           assert (0);
        }
     }
  
     return result;
  }
  
  DDSString be_DispatchableType::PutargMvalue
  (
     const be_CppName& argName,
     const be_ArgumentDirection& direction,
     int getargIndex
  ) const
  {
     DDSString result;
  
     switch (direction)
     {
        case VT_InOutParam:
        result = PutargMvalueInout (argName, getargIndex);
        break;
  
        case VT_Return:
        case VT_OutParam:
        result = PutargMvalueOutOrReturn (argName, direction, getargIndex);
        break;
  
        case VT_InParam:
        default:
        assert(0);
     }
  
     return result;
  }
  
  DDSString be_DispatchableType::PutargMvalueInout
  (
     const be_CppName& argName,
     int getargIndex
  ) const
  {
     DDSString result;
  
     switch (HowStoredInDispatcher (VT_InParam))
     {
        case STORED_AS_STACK_VARIABLE:
        case STORED_IN_VAR:
        case STORED_IN_STRING_VAR:
        case STORED_IN_ALLOCED_VAR:
        {
           result = "_out_[";
           result += getargIndex;
           result += "].m_value";
        }
        break;
  
        case STORED_IN_DESCENDANT_VAR:
        {
           result += "*(";
           result += ScopedName();
           result += "**)_out_[";
           result += getargIndex;
           result += "].m_value";
        }
        break;
  
        case STORED_IN_IOR_VAR:
        {
           result = "(";
           result += argName;
           result += ".in()) ? ";
           result += argName;
           result += "->get_ior() : 0";
        }
        break;
  
        default:
        {
           assert(0);
        }
     }
  
     return result;
  }
  
  DDSString be_DispatchableType::PutargMvalueOutOrReturn
  (
     const be_CppName & argName,
     const be_ArgumentDirection & direction,
     int getargIndex
  ) const
  {
     DDSString result;
  
     switch (HowStoredInDispatcher (direction))
     {
        case STORED_AS_STACK_VARIABLE:
        {
           result = "&";
           result += argName;
           break;
        }
        case STORED_IN_STRING_VAR:
        {
           result = "&";
           result += DDSString (argName) + DDSString (".val ()");
           break;
        }
        case STORED_IN_VAR:
        case STORED_IN_ALLOCED_VAR:
        case STORED_IN_DESCENDANT_VAR:
        {
           result = DDSString (argName) + DDSString (".val ()");
           break;
        }
        case STORED_IN_IOR_VAR:
        {
           result = DDSString ("(");
           result += DDSString (argName);
           result += DDSString (".in()) ? ");
           result += DDSString (argName);
           result += DDSString ("->get_ior () : 0");
           break;
        }
        default:
        {
           assert (0);
        }
     }
  
     return result;
  }
  
  void be_DispatchableType::InitializeInDispatcher
  (
     ostream&,
     be_Tab&,
     const be_CppName&,
     const be_ArgumentDirection&
  ) const
  {
  }
  