types.py :  » Development » omniORB » omniORB-4.1.4 » src » lib » omniORB » omniidl_be » cxx » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » omniORB 
omniORB » omniORB 4.1.4 » src » lib » omniORB » omniidl_be » cxx » types.py
# -*- python -*-
#                           Package   : omniidl
# types.py                  Created on: 2000/4/10
#          Author    : David Scott (djs)
#
#    Copyright (C) 2003-2009 Apasphere Ltd
#    Copyright (C) 1999 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:
#   
#   Type utility functions designed for the C++ backend

import string

try:
    # Python 3 does not have a built in reduce()
    from functools import reduce
except ImportError:
    pass

from omniidl import idltype,idlast,idlutil
from omniidl_be.cxx import util,config,id

# direction constants
IN     = 0
OUT    = 1
INOUT  = 2
RET    = 3

# we don't support these yet
unsupported_typecodes =[idltype.tk_Principal,
                        idltype.tk_native]

class Type:
    """Wrapper around an IDL type providing useful extra functionality"""
    def __init__(self, type):
        assert isinstance(type, idltype.Type)
        self.__type = type

    def type(self):
        """type(types.Type): idltype.Type
           returns the wrapped type"""
        return self.__type

    def kind(self):
        """type(types.Type): idltype.kind
           returns the kind of the wrapped type"""
        return self.__type.kind()

    def deref(self, keep_dims = 0):
        """deref(types.Type, keep_dims boolean option) -> types.Type
           Return the type with outer aliases removed.
           (if keep_dims is true then it will not remove aliases with
           array dimensions)"""
        type = self
        while (type.typedef()):
            decl = type.__type.decl()
            if keep_dims and decl.sizes() != []:
                return type
            type = Type(decl.alias().aliasType())

        return type

    def variable(self):
        """variable(types.Type): boolean
           Returns whether the type has a variable length representation
           under the C++ mapping"""
        type = self.__type

        if already_Variable.has_key(type.kind()):
            return already_Variable[type.kind()]

        if isinstance(type, idltype.Declared):
            decl = type.decl()
            return variableDecl(decl)

        util.fatalError("Error while computing the variable-ness of a type")

    def dims(self):
        """dims(types.Type): int list
           Returns the full dimensions of the type"""

        type = self.__type
        if isinstance(type, idltype.Declared):
            decl = type.decl()
            if type.kind() == idltype.tk_alias:
                sizes = []
                if decl.sizes() != None:
                    sizes = decl.sizes()
                if decl.alias() != None:
                    sizes = sizes + Type(decl.alias().aliasType()).dims()
                return sizes
            if isinstance(type.decl(), idlast.Typedef):
                return Type(type.decl().aliasType()).dims()
            return []
        return []

    def array(self):
        """array(types.Type): boolean
           Returns true if this type has array dimensions"""
        return self.dims() != []

    def __apply_mapping(self, (const, ref, ptr), thing):
        # __apply_mapping(types.Type, (const bool, ref bool, ptr bool), string)
        #  : string
        # Make an instance of "thing" which is optionally const, a reference
        # and a pointer types
        text = thing
        if const: text = "const " + text
        if ptr:   text = text + "*"
        if ref:   text = text + "&"
        return text
        
    def _argmapping(self, direction):
        # _argmapping(types.Type, int direction): const * reference * pointer
        #   Returns info on operation argument mapping for a type for
        #   a particular direction.

        # CORBA2.3 P1-204 Table 1-3 Basic argument and result mapping
        array = self.array()
        variable = self.variable()

        if array and not variable:
            # array of fixed size elements
            return ( (1, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 1) )[direction]

        if array and variable:
            # array of variable size elements
            return ( (1, 0, 0), (0, 1, 1), (0, 0, 0), (0, 0, 1) )[direction]

        type = self.deref().__type
        kind = type.kind()

        if kind in [ idltype.tk_short, idltype.tk_long, idltype.tk_longlong,
                     idltype.tk_ushort, idltype.tk_ulong, idltype.tk_ulonglong,
                     idltype.tk_float, idltype.tk_double, idltype.tk_enum,
                     idltype.tk_longdouble, idltype.tk_boolean,
                     idltype.tk_char, idltype.tk_wchar, idltype.tk_octet ]:
            # from short to enum the entries are the same
            return ( (0, 0, 0), (0, 1, 0), (0, 1, 0), (0, 0, 0) )[direction]

        if kind in [ idltype.tk_objref,
                     idltype.tk_TypeCode,
                     idltype.tk_abstract_interface,
                     idltype.tk_local_interface ]:

            # objref_ptr objref_ptr& objref_ptr& objref_ptr
            return ( (0, 0, 0), (0, 1, 0), (0, 1, 0), (0, 0, 0) )[direction]

        if kind in [ idltype.tk_struct, idltype.tk_union ]:
            if variable:
                # variable struct or union
                return ((1, 1, 0), (0, 1, 1), (0, 1, 0), (0, 0, 1))[direction]
            else:
                # fixed struct or union
                return ((1, 1, 0), (0, 1, 0), (0, 1, 0), (0, 0, 0))[direction]
                
        if kind in [ idltype.tk_string, idltype.tk_wstring ]:
            return ( (1, 0, 0), (0, 1, 0), (0, 1, 0), (0, 0, 0) )[direction]

        if kind in [ idltype.tk_sequence, idltype.tk_any ]:
            return ( (1, 1, 0), (0, 1, 1), (0, 1, 0), (0, 0, 1) )[direction]

        if kind == idltype.tk_fixed:
            return ( (1, 1, 0), (0, 1, 0), (0, 1, 0), (0, 0, 0) )[direction]

        if kind in [ idltype.tk_value,
                     idltype.tk_value_box ]:

            return ( (0, 0, 1), (0, 1, 1), (0, 1, 1), (0, 0, 1) )[direction]

        if kind == idltype.tk_void:
            return (0, 0, 0)

        if kind in unsupported_typecodes:
            util.unsupportedIDL()

        util.fatalError("Unknown type encountered (kind = " + str(kind) + ")")
        return

    def op_is_pointer(self, direction):
        if not self.array() and \
           (self.deref().string() or self.deref().wstring()):
            return 0
        return self._argmapping(direction)[2]

    def __var_argmapping(self, direction):
        # __var_argmapping(types.Type, direction): const * reference * pointer
        #  Returns info on argument mapping for a type in a _var
        #  context
        
        # CORBA2.3 P1-204 Table 1-4 T_var argument and result mapping
        kind = self.__type.kind()

        if (kind in [ idltype.tk_objref,
                      idltype.tk_struct,
                      idltype.tk_union,
                      idltype.tk_string,
                      idltype.tk_wstring,
                      idltype.tk_sequence,
                      idltype.tk_any,
                      idltype.tk_value,
                      idltype.tk_value_box,
                      idltype.tk_abstract_interface,
                      idltype.tk_local_interface ]
            or
            self.array()):

            return ( (1, 1, 0), (0, 1, 0), (0, 1, 0), (0, 0, 0) )[direction]

        util.fatalError("T_var argmapping requested for type with no such "
                        "concept")
        return

    def base(self, environment = None, gscope = 0):
        """base(types.Type, id.Environment option): C++ type string
           Returns a basic C++ mapped version of the type"""
        kind = self.kind()
        d_type = self.deref(1)
        d_kind = d_type.kind()

        # CORBA2.3 P1-15 1.5 Mapping for Basic Data Types
        if basic_map.has_key(kind):
            return basic_map[kind]
        if self.string() or d_type.string():
            return "char*"
        if self.wstring() or d_type.wstring():
            return "::CORBA::WChar*"
        if self.typecode():
            return "::CORBA::TypeCode_ptr"
        if self.any():
            return "::CORBA::Any"
        if self.void():
            return "void"
        if self.fixed():
            return "::CORBA::Fixed"
        if self.sequence():
            return self.sequenceTemplate(environment, gscope=gscope)

        name = id.Name(self.type().scopedName()).unambiguous(environment)
        if gscope:
            assert environment is None
            name = "::" + name

        if d_type.interface() or d_type.typecode():
            return name + "_ptr"
        else:
            return name

    def __base_type_OUT(self, environment = None):
        # ___base_type_OUT(types.Type, id.Environment option): special C++
        #  OUT type
        type = self.__type
        d_type = self.deref()
        d_kind = type.kind()
        if basic_map_out.has_key(d_kind):
            return basic_map_out[d_kind]
        if d_type.string():
            return "::CORBA::String_out"
        if d_type.wstring():
            return "::CORBA::WString_out"
        if d_type.typecode():
            return "::CORBA::TypeCode_OUT_arg"
        if d_type.any():
            return "::CORBA::Any_OUT_arg"
        if d_type.sequence():
            return Type(d_type.type().seqType()).__base_type_OUT(environment)

        name = id.Name(type.scopedName())
        uname = name.unambiguous(environment)

        return uname + "_out"

    def __base_type_INOUT(self, environment = None):
        # __base_type_INOUT(types.Type): special C++ INOUT type string
        
        d_type = self.deref()
        kind = d_type.kind()
        if d_type.string():
            return "::CORBA::String_INOUT_arg"
        if d_type.wstring():
            return "::CORBA::WString_INOUT_arg"
        if d_type.typecode():
            return "::CORBA::TypeCode_INOUT_arg"
        if d_type.any():
            return "::CORBA::Any_INOUT_arg"

        name = id.Name(self.type().scopedName())
        uname = name.unambiguous(environment)
        
        if d_type.interface():
            name = id.Name(d_type.type().scopedName())

            if d_type.objref():
                objref_name = name.prefix("_objref_")
            else:
                objref_name = name

            if d_type.type().scopedName() == ["CORBA", "Object"]:
                return "::CORBA::Object_INOUT_arg"

            return "_CORBA_ObjRef_INOUT_arg< " + objref_name.fullyQualify() + \
                   ", " + name.unambiguous(environment) + "_Helper >"

        if d_type.value() or d_type.valuebox():
            name = id.Name(d_type.type().scopedName())
            return "_CORBA_Value_INOUT_arg< " + name.fullyQualify() + \
                   ", " + name.unambiguous(environment) + "_Helper >"

        return uname + "_INOUT_arg"

    def op(self, direction, environment = None, use_out = 1):
        """op(types.Type, int direction, id.Environment option, use_out bool)
           : C++ type argument mapping"""
        type = Type(self.__type)
        d_type = type.deref()

        base = self.base(environment)

        old_sig = config.state['Old Signatures']

        # this is very superfluous:
        if not self.array():
            if d_type.any() and self.typedef() and not old_sig:
                if direction == OUT:
                    return d_type.__base_type_OUT(environment)


            if d_type.typecode() and not old_sig:
                if direction == OUT:
                    return d_type.__base_type_OUT(environment)
                elif direction == INOUT and use_out:
                    return d_type.__base_type_INOUT(environment)
                else:
                    base = d_type.base(environment)


        # Use the ObjRef template for non-arrays of objrefs rather than use
        # the (equivalent?) _out type?
        if not d_type.objref() or type.array():

            # if its an out type and a typedef (to a variable type),
            # use the predefined _out type
            if type.typedef() and type.variable() and direction == OUT:

                if (not d_type.string() or not d_type.wstring() or \
                    (d_type.string() and type.array()) or \
                    (d_type.wstring() and type.array())):

                    base = id.Name(type.__type.scopedName()).unambiguous(environment)
                    base = base + "_out"
                    return base
        # superfluous deref for a typedef to an objref
        if d_type.objref() and not type.array():
            base = d_type.base(environment)

        # Deal with special cases ----------------------------------
        if not self.array():

            if direction == OUT and not use_out:
                if d_type.string() and not old_sig:
                    return self.__base_type_OUT(environment)
                if d_type.wstring() and not old_sig:
                    return self.__base_type_OUT(environment)
                if d_type.interface() and not old_sig:
                    return self.__base_type_OUT(environment)
                if d_type.typecode() and not old_sig:
                    return self.__base_type_OUT(environment)
                if d_type.any() and not old_sig:
                    return self.__base_type_OUT(environment)
                
            if direction == OUT:
                if d_type.string():
                    return self.__base_type_OUT(environment)
                if d_type.wstring():
                    return self.__base_type_OUT(environment)
                if d_type.typecode():
                    return self.__base_type_OUT(environment)
                if d_type.interface():
                    return self.__base_type_OUT(environment)
                if d_type.any() and (not old_sig or use_out):
                    return self.__base_type_OUT(environment)
                if d_type.variable() and (not old_sig or use_out):
                    return self.__base_type_OUT(environment)

            if direction == INOUT:
                if d_type.string() and use_out:
                    return self.__base_type_INOUT(environment)
                if d_type.wstring() and use_out:
                    return self.__base_type_INOUT(environment)
                if d_type.typecode() and use_out:
                    return self.__base_type_INOUT(environment)
                if d_type.interface() and use_out:
                    return self.__base_type_INOUT(environment)
                
        if d_type.string() and not type.array():
            base = d_type.base(environment)

        if d_type.wstring() and not type.array():
            base = d_type.base(environment)
    
        # P1-104 mentions two cases: returning an array and a variable
        # array out argument. For the latter rely on the _out type
        if (type.array() and direction == RET):
            base = base + "_slice"
            
        mapping = self._argmapping(direction)
        
        return self.__apply_mapping(mapping, base)

    def member(self, environment = None, decl = None, gscope = 0):
        """member(types.Type, id.Environment option, idlast.Declarator option):
           C++ member type"""

        if gscope:
            assert environment is None

        decl_dims = []
        if decl != None:
            assert isinstance(decl, idlast.Declarator)
            decl_dims = decl.sizes()

        is_array_declarator = decl_dims != []

        if not self.array():
            d_type = self.deref()
            if d_type.string():
                return "::CORBA::String_member"
            if d_type.wstring():
                return "::CORBA::WString_member"
            if d_type.interface():
                return d_type.objRefTemplate("Member", environment,
                                             gscope=gscope)
            if d_type.typecode():
                return "::CORBA::TypeCode_member"

            if self.sequence():
                return d_type.sequenceTemplate(environment, gscope=gscope)

            if self.value() or self.valuebox():
                m = self.base(environment) + "_member"
                if gscope: m = "::" + m
                return m

        if self.typedef():
            # for the type to have dimensions, it must be a typedef
            m = id.Name(self.__type.scopedName()).unambiguous(environment)
            if gscope: m = "::" + m
            return m

        return self.base(environment, gscope=gscope)

    def objRefTemplate(self, suffix, environment = None, gscope = 0):
        """objRefTemplate(types.Type, suffix string, id.Environment option):
           Returns a template objref instance for the current type"""
        type = self.deref().__type
        name = type.decl().scopedName()
        if name == ["CORBA", "Object"]:
            return "::CORBA::Object_" + suffix

        name = id.Name(name)
        uname = name.unambiguous(environment)
        if self.objref():
            objref_name = name.prefix("_objref_")
            objref_uname = objref_name.unambiguous(environment)
        else:
            objref_uname = uname

        if gscope:
            uname = "::" + uname
            objref_uname = "::" + objref_uname

        return "_CORBA_ObjRef_" + suffix + \
               "< " + objref_uname + ", " + uname + "_Helper> "

    def valueTemplate(self, suffix, environment = None, gscope = 0):
        """valueTemplate(types.Type, suffix string, id.Environment option):
           Returns a template value instance for the current type"""
        type = self.deref().__type
        name = type.decl().scopedName()
        name = id.Name(name)
        uname = name.unambiguous(environment)
        if gscope:
            uname = "::" + uname

        return "_CORBA_Value_%s< %s, %s > " % (suffix, uname,
                                               uname + "_Helper")

    def literal(self, value, environment = None):
        """literal(types.Type, value any, id.Environment option): string
           Returns a C++ representation of a value"""

        type = self.deref()
        kind = type.__type.kind()

        # (unsigned) short ints are themselves
        if kind in [ idltype.tk_short, idltype.tk_ushort ]:
            return str(value)

        # careful with long ints to avoid "L" postfix
        if kind in [ idltype.tk_long, idltype.tk_ulong ]:
            s = str(value)
            if s[-1] == 'L':             s = s[0:-1]
            if kind == idltype.tk_ulong: s = s + "U"
            return s

        if kind in [ idltype.tk_longlong, idltype.tk_ulonglong ]:
            s = str(value)
            if s[-1] == 'L':                 s = s[:-1]
            if kind == idltype.tk_ulonglong: s = s + "U"
            return "_CORBA_LONGLONG_CONST(" + s + ")"

        if kind in [ idltype.tk_float ]:
            return idlutil.reprFloat(value) + "F"

        if kind in [ idltype.tk_double ]:
            return idlutil.reprFloat(value)

        if kind in [ idltype.tk_longdouble ]:
            return idlutil.reprFloat(value) + "L"

        # chars are single-quoted
        if kind in [ idltype.tk_char ]:
            return "'" + idlutil.escapifyString(value) + "'"

        if kind in [ idltype.tk_wchar ]:
            return "L'" + idlutil.escapifyWString([value], "x") + "'"
        
        # booleans are straightforward
        if kind in [ idltype.tk_boolean ]:
            return str(value)

        if kind in [ idltype.tk_enum ]:
            # value is an enumerator
            enum_name = id.Name(value.scopedName())
            #enum_name = id.Name(type.__type.decl().scopedName() + [str(value)])
            return enum_name.unambiguous(environment)

        if kind in [ idltype.tk_string ]:
            return '"' + idlutil.escapifyString(value) + '"'

        if kind in [ idltype.tk_wstring ]:
            return 'L"' + idlutil.escapifyWString(value, "x") + '"'

        if kind in [ idltype.tk_octet ]:
            return str(value)

        if kind in [ idltype.tk_fixed ]:
            return '"' + value + '"'

        util.fatalError("Internal error when handling value (" +\
                        repr(value) +")" )

    def sequenceTemplate(self, environment = None, gscope = 0):
        """sequenceTemplate(types.Type, id.Environment option): C++ template
           Returns a C++ template instance for the current type as a
           sequence"""
        # returns a template instantiation suitable for the
        # sequence type
        # (similar in function to o2be_sequence::seq_template_name)
        sequence = self.__type
        assert isinstance(sequence, idltype.Sequence)
        
        SeqType = Type(sequence.seqType())
        d_SeqType = SeqType.deref()
        SeqTypeID = SeqType.base(environment, gscope=gscope)
        d_SeqTypeID = d_SeqType.base(environment, gscope=gscope)
        if d_SeqType.typecode():
            d_SeqTypeID = "::CORBA::TypeCode_member"
            SeqTypeID = "::CORBA::TypeCode_member"
        elif d_SeqType.interface():
            d_SeqTypeID = string.replace(d_SeqTypeID,"_ptr","")
            SeqTypeID = string.replace(SeqTypeID,"_ptr","")
        elif d_SeqType.string():
            d_SeqTypeID = "::CORBA::String_member"
        elif d_SeqType.wstring():
            d_SeqTypeID = "::CORBA::WString_member"
        
        if SeqType.string():
            SeqTypeID = "::CORBA::String_member"

        if SeqType.wstring():
            SeqTypeID = "::CORBA::WString_member"

        # silly special case (not needed?):
        #if d_SeqType.objref() and SeqType.typedef():
        #    SeqTypeID = id.Name(SeqType.type().scopedName()).\
        #                unambiguous(environment)

        seq_dims = SeqType.dims()
        is_array = seq_dims != []
        dimension = reduce(lambda x,y: x * y, seq_dims, 1)

        template = {}
        template["bounded"]   = sequence.bound()
        template["array"]     = is_array
        template["dimension"] = dimension
        
        template["seqTypeID"] = SeqTypeID
        template["derefSeqTypeID"] = d_SeqTypeID

        # if the seqType is a typedef to a sequence, use the typedef name
        # else if a direct sequence<sequence<...., do recursion
        if d_SeqType.sequence() and not SeqType.typedef():
            element_template = d_SeqType.sequenceTemplate(environment)
            template["seqTypeID"] = element_template
            template["derefSeqTypeID"] = element_template

        if is_array:
            if d_SeqType.sequence():
                template["derefSeqTypeID"] = d_SeqType.\
                                             sequenceTemplate(environment)
        
        if d_SeqType.char():
            template["suffix"] = "_Char"
        elif d_SeqType.wchar():
            template["suffix"] = "_WChar"
        elif d_SeqType.boolean():
            template["suffix"] = "_Boolean"
        elif d_SeqType.octet():
            template["suffix"] = "_Octet"
            # strings are always special
        elif d_SeqType.string() and not is_array:
            template["suffix"] = "_String"
        elif d_SeqType.wstring() and not is_array:
            template["suffix"] = "_WString"
        elif d_SeqType.structforward() or d_SeqType.unionforward():
            template["forward"] = 1
        elif typeSizeAlignMap.has_key(d_SeqType.type().kind()):
            template["fixed"] = typeSizeAlignMap[d_SeqType.type().kind()]
        elif d_SeqType.interface():
            scopedName = d_SeqType.type().decl().scopedName()
            is_CORBA_Object = scopedName == ["CORBA", "Object"]
            scopedName = id.Name(scopedName)
            
            if not is_CORBA_Object and d_SeqType.objref():
                # CORBA::Object doesn't have an _objref_xxx
                scopedName = scopedName.prefix("_objref_")
           
            objref_name = scopedName.unambiguous(environment)

            if not is_array:
                objref_template = d_SeqType.objRefTemplate("Element", environment)
            else:
                objref_template = d_SeqType.objRefTemplate("Member", environment)
            template["objref_name"]     = objref_name
            template["objref_template"] = objref_template
            template["objref_helper"]   = SeqTypeID + "_Helper"
            template["objref"]          = 1

        elif d_SeqType.value() or d_SeqType.valuebox():
            scopedName = d_SeqType.type().decl().scopedName()
            scopedName = id.Name(scopedName)
            
            value_name = scopedName.unambiguous(environment)

            if not is_array:
                value_template = d_SeqType.valueTemplate("Element", environment)
            else:
                value_template = d_SeqType.valueTemplate("Member", environment)

            template["value_name"]     = value_name
            template["value_template"] = value_template
            template["value_helper"]   = SeqTypeID + "_Helper"
            template["value"]          = 1

        return self.__templateToString(template)

    # converts a hash of template properties into a template instance
    def __templateToString(self, template):
        # ------------------------------------
        # work out the template name
        if template["bounded"]:
            name = "_CORBA_Bounded_Sequence"
        else:
            name = "_CORBA_Unbounded_Sequence"

        if template["array"]:
            name = name + "_Array"
        
        if template.has_key("suffix"):
            name = name + template["suffix"]

        if template.has_key("forward"):
            name = name + "_Forward"

        elif template.has_key("objref") and not template["array"]:
            name = name + "_ObjRef"

        elif template.has_key("value") and not template["array"]:
            name = name + "_Value"

        if template.has_key("fixed"):
            name = name + "_w_FixSizeElement"

        # ------------------------------------
        # build the argument list
        args = []

        seqTypeID      = template["seqTypeID"]
        derefSeqTypeID = template["derefSeqTypeID"]
        dimension      = template["dimension"]

        # Note the difference between an ObjRef and an array of ObjRefs
        if template["array"]:
            args.extend([seqTypeID, seqTypeID + "_slice"])
        
            if template.has_key("objref"):
                args.append(template["objref_template"])

            elif template.has_key("value"):
                args.append(template["value_template"])

            elif not template.has_key("suffix"):
                # __Boolean __Octet __String
                # these already contain the type info- no need for another
                # parameter...
                args.append(derefSeqTypeID)
                
            args.append(str(dimension))
        
        elif template.has_key("objref"):
            args.extend([template["objref_name"],
                         template["objref_template"],
                         template["objref_helper"]])

        elif template.has_key("value"):
            args.extend([template["value_name"],
                         template["value_template"],
                         template["value_helper"]])

        elif not template.has_key("suffix"):
            # see above
            args.append(seqTypeID)
        
        if template.has_key("bounded") and \
           template["bounded"]:
            args.append(str(template["bounded"]))

        if template.has_key("fixed"):
            (element_size, alignment) = template["fixed"]
            args.extend([str(element_size), str(alignment)])

        # -----------------------------------
        # build the template instance
        if args:
            name = name + "< " + string.join(args, ", ") + " > "
            return name

        return name

    def _var(self, environment = None):
        """Returns a representation of the type which is responsible for its
           own destruction. Assigning a heap allocated thing to this type
           should allow the user to forget about deallocation."""
        d_T = self.deref()

        if self.array() or d_T.struct()    or d_T.union() or \
                           d_T.exception() or d_T.sequence() or \
                           d_T.interface() or d_T.value() or \
                           d_T.valuebox():
            name = id.Name(self.type().decl().scopedName()).suffix("_var")
            return name.unambiguous(environment)

        if d_T.typecode(): return "::CORBA::TypeCode_var"
        if d_T.any():      return "::CORBA::Any_var"
        if d_T.string():   return "::CORBA::String_var"
        if d_T.wstring():  return "::CORBA::WString_var"
        if d_T.enum():
            name = id.Name(self.type().decl().scopedName())
            return name.unambiguous(environment)
        
        if self.is_basic_data_types():
            return basic_map[d_T.kind()]
        
        if d_T.void():
            raise NotImplementedError("No such thing as a void _var type")

        raise "Unknown _var type, kind = " + str(d_T.kind())

    def out(self, ident):
        if self.is_basic_data_types():
            return ident
        
        return ident + ".out()"

    def free(self, thing, environment = None):
        """Ensures that any heap allocated storage associated with this type
           has been deallocated."""

        if self.array():
            name = id.Name(self.type().decl().scopedName()).suffix("_free")
            return name.unambiguous(environment) + "(" + thing + ");"

        d_T = self.deref()

        if d_T.interface() or d_T.typecode():
            return "::CORBA::release(" + thing + ");"
        if d_T.string():   return "::CORBA::string_free(" + thing + ");"

        if d_T.wstring():   return "::CORBA::wstring_free(" + thing + ");"

        if d_T.struct() or d_T.union() or d_T.exception() or \
           d_T.sequence() or d_T.any():
            if d_T.variable():
                return "delete " + thing + ";"
            return "" # stored by value

        if d_T.enum() or d_T.void() or (self.is_basic_data_types()):
            return ""

        raise "Don't know how to free type, kind = " + str(d_T.kind())

    def copy(self, src, dest, environment = None):
        """Copies an entity from src to dest"""

        if self.array():
            name = id.Name(self.type().decl().scopedName()).suffix("_dup")
            return dest + " = " + name.unambiguous(environment) + "("+src+");"

        d_T = self.deref()
        if d_T.typecode():
            return dest + " = ::CORBA::TypeCode::_duplicate(" + src + ");"
        if d_T.interface():
            # Use the internal omniORB duplicate function in case the
            # normal one isn't available
            name = id.Name(self.type().decl().scopedName()).suffix("_Helper")
            return name.unambiguous(environment) + "::duplicate" +\
                   "(" + src + ");\n" + dest + " = " + src + ";"
        if d_T.string():
            return dest + " = ::CORBA::string_dup(" + src + ");"
        if d_T.wstring():
            return dest + " = ::CORBA::wstring_dup(" + src + ");"
        if d_T.any():
            return dest + " = new ::CORBA::Any(" + src + ");"
        
        if d_T.struct() or d_T.union() or d_T.exception() or d_T.sequence():
            name = id.Name(self.type().decl().scopedName()).\
                   unambiguous(environment)
            if d_T.variable():
                return dest + " = new " + name + "(" + src + ");"
            return dest + " = " + src + ";"
        
        if d_T.enum() or self.is_basic_data_types():
            return dest + " = " + src + ";"

        raise "Don't know how to copy type, kind = " + str(d_T.kind())
               
    def representable_by_int(self):
        """representable_by_int(types.Type): boolean
           Returns true if the type is representable by an integer"""
        return self.integer() or self.char() or self.boolean() or self.octet()

    def is_basic_data_types(self):
        d_T = self.deref()
        return basic_map.has_key(d_T.kind())
        
    def integer(self):
        type = self.__type
        return type.kind() in [ idltype.tk_short, idltype.tk_long,
                                idltype.tk_longlong, idltype.tk_ushort,
                                idltype.tk_ulong, idltype.tk_ulonglong ]
    def char(self):
        type = self.__type
        return type.kind() == idltype.tk_char

    def wchar(self):
        type = self.__type
        return type.kind() == idltype.tk_wchar
        
    def floating(self):
        type = self.__type
        return type.kind() in [ idltype.tk_float, idltype.tk_double ]

    def float(self):
        type = self.__type
        return type.kind() == idltype.tk_float

    def double(self):
        type = self.__type
        return type.kind() == idltype.tk_double    

    def boolean(self):
        type = self.__type
        return type.kind() == idltype.tk_boolean

    def enum(self):
        type = self.__type
        return type.kind() == idltype.tk_enum

    def octet(self):
        type = self.__type
        return type.kind() == idltype.tk_octet

    def string(self):
        type = self.__type
        return type.kind() == idltype.tk_string

    def wstring(self):
        type = self.__type
        return type.kind() == idltype.tk_wstring

    def objref(self):
        type = self.__type
        return type.kind() == idltype.tk_objref

    def sequence(self):
        type = self.__type
        return type.kind() == idltype.tk_sequence

    def typecode(self):
        type = self.__type
        return type.kind() == idltype.tk_TypeCode

    def typedef(self):
        type = self.__type
        return type.kind() == idltype.tk_alias

    def struct(self):
        type = self.__type
        return type.kind() == idltype.tk_struct

    def structforward(self):
        type = self.__type
        return type.kind() == idltype.ot_structforward

    def union(self):
        type = self.__type
        return type.kind() == idltype.tk_union

    def unionforward(self):
        type = self.__type
        return type.kind() == idltype.ot_unionforward

    def exception(self):
        type = self.__type
        return type.kind() == idltype.tk_except
    
    def void(self):
        type = self.__type
        return type.kind() == idltype.tk_void

    def any(self):
        type = self.__type
        return type.kind() == idltype.tk_any

    def fixed(self):
        type = self.__type
        return type.kind() == idltype.tk_fixed

    def value(self):
        type = self.__type
        return type.kind() == idltype.tk_value

    def valuebox(self):
        type = self.__type
        return type.kind() == idltype.tk_value_box

    def abstract_interface(self):
        type = self.__type
        return type.kind() == idltype.tk_abstract_interface

    def local_interface(self):
        type = self.__type
        return type.kind() == idltype.tk_local_interface

    def interface(self):
        type = self.__type
        return type.kind() in [ idltype.tk_objref,
                                idltype.tk_abstract_interface,
                                idltype.tk_local_interface ]


def variableDecl(decl):
    """types.variableDecl(idlast.Decl): boolean
        Returns true if the declaration represents a variable type"""
    # interfaces are mapped to objects, which are always
    # variable types. same goes for exceptions.
    if isinstance(decl, idlast.Interface)       or \
       isinstance(decl, idlast.Forward)         or \
       isinstance(decl, idlast.Exception):
        return 1
    elif isinstance(decl, idlast.Const)         or \
         isinstance(decl, idlast.Enum):
        return 0
    
    # a typedef is only a type alias- as such it has no storage
    # at all. However it eventually points to something that would.
    elif isinstance(decl, idlast.Typedef):
        return Type(decl.aliasType()).variable()
    
    # a structure is variable if any one of its constituents
    # is also variable
    elif isinstance(decl, idlast.Struct):
        for m in decl.members():
            if Type(m.memberType()).variable():
                return 1
        return 0
        
    # a union is variable if any one if its constituents
    # is also variable
    elif isinstance(decl, idlast.Union):
        for c in decl.cases():
            if Type(c.caseType()).variable():
                return 1
        return 0

    # a declarator is variable if it is an alias to a variable
    # type
    elif isinstance(decl, idlast.Declarator) and \
         decl.alias() != None:
        return Type(decl.alias().aliasType()).variable()

    util.fatalError("Unknown AST node, scopedName = " +repr(decl.scopedName()))




def direction(param):
    if param.is_in() and param.is_out():
        return INOUT
    elif param.is_in():
        return IN
    elif param.is_out():
        return OUT

    # Top 12 things likely to be overheard from a Klingon Programmer: 
    # ...
    #
    #   7) "Klingon function calls do not have 'parameters' - they
    #       have 'arguments' - and they ALWAYS WIN THEM."
    # ...

    util.fatalError("Illegal parameter direction")


#################################################################
# Tables of useful data ripped from the CORBA spec

# already_Variable maps typecode kinds onto true/ false
# 
# An entry in this table indicates we already know is a type is
# variable or not, without having to look at its declaration.
# (note that eg structs and unions are only variable if one of
#  their members are)

# CORBA2.3 P1-21 1.9 Mapping for Structured Types
already_Variable = {
    idltype.tk_null:               0,
    idltype.tk_void:               0,
    idltype.tk_short:              0,
    idltype.tk_long:               0,
    idltype.tk_ushort:             0,
    idltype.tk_ulong:              0,
    idltype.tk_float:              0,
    idltype.tk_double:             0,
    idltype.tk_boolean:            0,
    idltype.tk_char:               0,
    idltype.tk_octet:              0,
    idltype.tk_any:                1,
    idltype.tk_objref:             1,
    idltype.tk_string:             1,
    idltype.tk_sequence:           1,
    idltype.tk_except:             1,
    idltype.tk_longlong:           0,
    idltype.tk_ulonglong:          0,
    idltype.tk_longdouble:         0,
    idltype.tk_wchar:              0,
    idltype.tk_wstring:            1,
    idltype.tk_fixed:              0,          
    idltype.tk_value:              1,      
    idltype.tk_value_box:          1,      
    idltype.tk_abstract_interface: 1,
    idltype.tk_TypeCode:           1,
    idltype.tk_local_interface:    1,
    }

# CORBA2.3 P1-15 1.5 Mapping for Basic Data Types
basic_map = {
    idltype.tk_short:              "::CORBA::Short",
    idltype.tk_long:               "::CORBA::Long",
    idltype.tk_longlong:           "::CORBA::LongLong",
    idltype.tk_ushort:             "::CORBA::UShort",
    idltype.tk_ulong:              "::CORBA::ULong",
    idltype.tk_ulonglong:          "::CORBA::ULongLong",
    idltype.tk_float:              "::CORBA::Float",
    idltype.tk_double:             "::CORBA::Double",
    idltype.tk_longdouble:         "::CORBA::LongDouble",
    idltype.tk_char:               "::CORBA::Char",
    idltype.tk_wchar:              "::CORBA::WChar",
    idltype.tk_boolean:            "::CORBA::Boolean",
    idltype.tk_octet:              "::CORBA::Octet"
    }
basic_map_out = { }
for key,value in basic_map.items():
    basic_map_out[key] = value + "_out"


# Info on size and alignment of basic types
typeSizeAlignMap = {
    idltype.tk_char:      (1, 1),
    idltype.tk_boolean:   (1, 1),
    idltype.tk_wchar:     (2, 2),
    idltype.tk_short:     (2, 2),
    idltype.tk_ushort:    (2, 2),
    idltype.tk_long:      (4, 4),
    idltype.tk_ulong:     (4, 4),
    idltype.tk_float:     (4, 4),
    idltype.tk_enum:      (4, 4),
    idltype.tk_double:    (8, 8),
    idltype.tk_octet:     (1, 1),
    idltype.tk_longlong:  (8, 8),
    idltype.tk_ulonglong: (8, 8)
    }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.