📄 call.py
字号:
# -*- python -*-# Package : omniidl# call.py Created on: 2000/08/03# Author : David Scott (djs)## Copyright (C) 2000 AT&T Laboratories Cambridge## This file is part of omniidl.## omniidl is free software; you can redistribute it and/or modify it# under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA# 02111-1307, USA.## Description:# Produce local callback functions## $Id: call.py,v 1.1.4.15 2005/03/29 15:52:54 dgrisby Exp $# $Log: call.py,v $# Revision 1.1.4.15 2005/03/29 15:52:54 dgrisby# Change on 1st July to void operation call descriptors broke with# compilers that cannot catch by base class.## Revision 1.1.4.14 2004/07/01 19:13:32 dgrisby# Suppress compiler warnings on void methods. Thanks Peter Klotz.## Revision 1.1.4.13 2003/01/14 11:48:16 dgrisby# Remove warnings from gcc -Wshadow. Thanks Pablo Mejia.## Revision 1.1.4.12 2002/11/21 16:12:34 dgrisby# Oneway call descriptor bug.## Revision 1.1.4.11 2001/11/27 14:35:08 dpg1# Context, DII fixes.## Revision 1.1.4.10 2001/11/06 15:41:37 dpg1# Reimplement Context. Remove CORBA::Status. Tidying up.## Revision 1.1.4.9 2001/10/18 12:45:27 dpg1# IDL compiler tweaks.## Revision 1.1.4.8 2001/10/17 16:50:25 dpg1# Incorrect code with multiple out arguments## Revision 1.1.4.7 2001/08/15 10:26:10 dpg1# New object table behaviour, correct POA semantics.## Revision 1.1.4.6 2001/05/31 16:18:11 dpg1# inline string matching functions, re-ordered string matching in# _ptrToInterface/_ptrToObjRef## Revision 1.1.4.5 2001/05/02 14:20:15 sll# Make sure that getStream() is used instead of casting to get a cdrStream# from a IOP_C and IOP_S.## Revision 1.1.4.4 2001/04/19 09:30:12 sll# Big checkin with the brand new internal APIs.# Scoped where appropriate with the omni namespace.## Revision 1.1.4.3 2000/11/07 18:27:31 sll# out_objrefcall now generates the correct unambiguous type name in its castings.## Revision 1.1.4.2 2000/11/03 19:25:23 sll# A new class CallDescriptor. The class contains all the code to generate# the call descriptor for each operation. It also has functions to be called# by different parts of the stub that use the call descriptor.## Revision 1.1.4.1 2000/10/12 15:37:46 sll# Updated from omni3_1_develop.## Revision 1.1.2.2 2000/09/14 16:03:01 djs# Remodularised C++ descriptor name generator# Bug in listing all inherited interfaces if one is a forward# repoID munging function now handles #pragma ID in bootstrap.idl# Naming environments generating code now copes with new IDL AST types# Modified type utility functions# Minor tidying## Revision 1.1.2.1 2000/08/21 11:34:32 djs# Lots of omniidl/C++ backend changes#"""Produce call descriptors and local callback functions"""from omniidl import idlast, idltypefrom omniidl_be.cxx import types, id, util, skutil, output, cxx, ast, descriptorfrom omniidl_be.cxx.skel import mangler, templateimport string# Callable- represents the notion of a callable entity (eg operation or# attribute accessor method). Note that a read/write attribute is really# two such entities paired together.## .interface(): get the associated Interface object# .operation_name(): get the IIOP operation name (eg get_colour)# .method_name(): get the C++ mapped method name (eg colour)# .returnType(): idltype# .parameters(): idlast.Parameter# .oneway(): boolean# .contexts():# .signature(): string representing the IDL signature# .method(use_out): C++ mapping#class Callable: def __init__(self, interface, operation_name, method_name, returnType, parameters, oneway = 0, raises = [], contexts = []): self.__interface = interface self.__operation_name = operation_name self.__method_name = method_name self.__returnType = returnType self.__parameters = parameters self.__oneway = oneway self.__raises = raises self.__contexts = contexts self.__signature = mangler.produce_signature(returnType, parameters, raises, oneway) def interface(self): return self.__interface def operation_name(self): return self.__operation_name def method_name(self): return self.__method_name def returnType(self): return self.__returnType def parameters(self): return self.__parameters def oneway(self): return self.__oneway def raises(self): return self.__raises def contexts(self): return self.__contexts def signature(self): return self.__signature# Utility functions to build Callables ##################################def operation(interface, operation): assert isinstance(operation, idlast.Operation) return Callable(interface, operation.identifier(), id.mapID(operation.identifier()), operation.returnType(), operation.parameters(), operation.oneway(), operation.raises(), operation.contexts())def read_attributes(interface, attribute): assert isinstance(attribute, idlast.Attribute) callables = [] for identifier in attribute.identifiers(): callables.append(Callable(interface, "_get_" + identifier, id.mapID(identifier), attribute.attrType(), [], 0, [], [])) return callablesdef write_attributes(interface, attribute): assert isinstance(attribute, idlast.Attribute) voidType = idltype.Base(idltype.tk_void) callables = [] param = idlast.Parameter(attribute.file(), attribute.line(), attribute.mainFile(), [], [], 0, attribute.attrType(), "_v") for identifier in attribute.identifiers(): callables.append(Callable(interface, "_set_" + identifier, id.mapID(identifier), voidType, [param], 0, [], [])) return callables#####################################################################class CallDescriptor:# How this works:## A call descriptor can be used on both sides:# 1. on the client side to drive a remote call# 2. on the server side to drive an upcall## Therefore, it has to have a way to hold the arguments that is suitable# for both the client and the server side.## On the server side there is an additional requirement that it must# provide the storage for the in and inout arguments.## For this requirement, the call descriptor must contain 2 member per# argument:# 1. an argument holder, as the name suggests, is to hold the argument# passed by the proxy call on the client side.# 2. an argument storage which is used to store the argument and to# remove it from the heap when finished.## The naming convention is that a holder is named "arg_n" and# a storage is named "arg_n_".## In many cases, the holder member is the same as the storage member. Under# these circumstances, only a single member is provided in the call descriptor# and is named "arg_n".## Some examples:## For a string IN argument, the call descriptor members are:# const char* arg_0;# CORBA::String_var arg_0_;## For a string OUT argument, the member is just# CORBA::String_var arg_0;## For a variable length struct IN argument:# const varStruct* arg_0;# varStruct_var arg_0_;# Notice that the argument holder is a pointer to the struct whereas# the mapping signature is const varStruct&.## To determine what is most appropriate given a type and direction combination,# the helper function _arg_info() is defined. The function is called with# the type and direction as input and it returns a tuple of this form:# ((is_const, is_ptr), (same_as_holder, is_var))## The 1st element of the tuple describes the argument holder. The element# itself is also a tuple:# is_const == 1 if the holder is a const (e.g. IN string)# is_ptr == 1 if the holder is a pointer (e.g. IN varStruct and ! IN string)# # The 2nd decribes the argument storage:# same_as_holder == 1 if both holder & storage are the same (e.g. OUT string)# is_var == 1 if the storage is a _var type (e.g. OUT string, OUT varStruct).# If it is a _var type, of course the actual storage for# the argument must be allocated on the heap.## All the member functions of this class generates code based on this tuple# def __init__(self,signature,callable): self.__signature = signature self.__name = descriptor.call_descriptor(signature) self.__oneway = callable.oneway() self.__arguments = callable.parameters() self.__returntype = callable.returnType() self.__exceptions = callable.raises() self.__contexts = callable.contexts() self.__has_in_args = 0 self.__has_out_args = 0 self.__has_return_value = 0 for argument in self.__arguments: if argument.is_in(): self.__has_in_args = 1 if argument.is_out(): self.__has_out_args = 1 if self.__returntype.kind() != idltype.tk_void: self.__has_return_value = 1 if self.__contexts: self.__context_name = descriptor.\ context_descriptor(self.__signature) def out_desc(self, stream): self.__out_declaration(stream) self.__out_contextDescriptor(stream) self.__out_marshalArgument(stream) self.__out_unmarshalArgument(stream) self.__out_marshalReturnedValues(stream) self.__out_unmarshalReturnedValues(stream) self.__out_userException(stream) def out_localcall(self, stream, interface_name, operation, function_name): assert isinstance(stream, output.Stream) assert isinstance(interface_name, id.Name) impl_args = [] n = -1 for argument in self.__arguments:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -