skutil.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 » skutil.py
# -*- python -*-
#                           Package   : omniidl
# skutil.py                 Created on: 1999/11/15
#          Author    : David Scott (djs)
#
#    Copyright (C) 2003-2008 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:
#   
#   Skeleton utility functions designed for the C++ backend

# $Id: skutil.py,v 1.20.2.13 2009/05/06 16:15:52 dgrisby Exp $
# $Log: skutil.py,v $
# Revision 1.20.2.13  2009/05/06 16:15:52  dgrisby
# Update lots of copyright notices.
#
# Revision 1.20.2.12  2008/12/03 10:53:58  dgrisby
# Tweaks leading to Python 3 support; other minor clean-ups.
#
# Revision 1.20.2.11  2007/09/19 14:16:08  dgrisby
# Avoid namespace clashes if IDL defines modules named CORBA.
#
# Revision 1.20.2.10  2007/04/12 19:50:32  dgrisby
# A few cases of sizeof(bool) > 1 were not handled correctly.
#
# Revision 1.20.2.9  2006/04/28 18:40:46  dgrisby
# Merge from omni4_0_develop.
#
# Revision 1.20.2.8  2005/11/09 12:22:17  dgrisby
# Local interfaces support.
#
# Revision 1.20.2.7  2005/08/16 13:51:21  dgrisby
# Problems with valuetype / abstract interface C++ mapping.
#
# Revision 1.20.2.6  2005/01/06 23:09:50  dgrisby
# Big merge from omni4_0_develop.
#
# Revision 1.20.2.5  2004/10/13 17:58:22  dgrisby
# Abstract interfaces support; values support interfaces; value bug fixes.
#
# Revision 1.20.2.4  2004/02/16 10:10:30  dgrisby
# More valuetype, including value boxes. C++ mapping updates.
#
# Revision 1.20.2.3  2003/10/23 11:25:54  dgrisby
# More valuetype support.
#
# Revision 1.20.2.2  2003/05/20 16:53:14  dgrisby
# Valuetype marshalling support.
#
# Revision 1.20.2.1  2003/03/23 21:02:41  dgrisby
# Start of omniORB 4.1.x development branch.
#
# Revision 1.17.2.9  2001/06/19 16:41:49  sll
# Type cast now correctly distinguishes between normal and array types.
#
# Revision 1.17.2.8  2001/06/19 14:23:21  sll
# In the marshalling and unmarshalling code, only cast from a sequence T_var to
# T&. Otherwise, the generate code is wrong with gcc 3.0. Suppose T is a
# sequence of A, even though T is always a derived class of the template
# instance seq<A>, casting a T_var to a seq<A>& causes GCC 3.0 to generate
# wrong code quietly!
#
# Revision 1.17.2.7  2001/06/15 10:22:09  sll
# Work around for MSVC++ bug. Changed the casting of the array of base types
# when they are marshalled using the quick method.
#
# Revision 1.17.2.6  2001/06/08 17:12:13  dpg1
# Merge all the bug fixes from omni3_develop.
#
# Revision 1.17.2.5  2001/04/19 10:04:13  dpg1
# Bug in sort_exceptions()
#
# Revision 1.17.2.4  2000/11/07 18:28:21  sll
# Use helper marshal functions if the interface is a forward declaration.
#
# Revision 1.17.2.3  2000/11/03 19:26:01  sll
# Simplified the marshalling functions.
#
# Revision 1.17.2.2  2000/10/12 15:37:48  sll
# Updated from omni3_1_develop.
#
# Revision 1.18.2.2  2000/08/21 11:34:35  djs
# Lots of omniidl/C++ backend changes
#
# Revision 1.18.2.1  2000/08/04 17:10:26  dpg1
# Long long support
#
# Revision 1.18  2000/07/13 15:26:01  dpg1
# Merge from omni3_develop for 3.0 release.
#
# Revision 1.15.2.4  2000/05/31 18:02:16  djs
# Better output indenting (and preprocessor directives now correctly output at
# the beginning of lines)
#
# Revision 1.15.2.3  2000/04/26 18:22:13  djs
# Rewrote type mapping code (now in types.py)
# Rewrote identifier handling code (now in id.py)
#
# Revision 1.15.2.2  2000/03/09 15:21:40  djs
# Better handling of internal compiler exceptions (eg attempts to use
# wide string types)
#
# Revision 1.15.2.1  2000/02/14 18:34:57  dpg1
# New omniidl merged in.
#
# Revision 1.15  2000/01/17 16:58:52  djs
# Marshalling code: exceptions (BAD_PARAM, MARSHAL) and bounded strings
#
# Revision 1.14  2000/01/11 12:02:34  djs
# More tidying up
#
# Revision 1.13  2000/01/07 20:31:18  djs
# Regression tests in CVSROOT/testsuite now pass for
#   * no backend arguments
#   * tie templates
#   * flattened tie templates
#   * TypeCode and Any generation
#
# Revision 1.12  1999/12/26 16:38:06  djs
# Support for bounded strings (specifically a bounds check raising
# CORBA::BAD_PARAM)
#
# Revision 1.11  1999/12/16 16:08:02  djs
# More TypeCode and Any fixes
#
# Revision 1.10  1999/12/15 12:11:54  djs
# Marshalling arrays of Anys fix
#
# Revision 1.9  1999/12/14 11:53:56  djs
# Support for CORBA::TypeCode and CORBA::Any
#
# Revision 1.8  1999/12/10 18:26:03  djs
# Added a utility function to order exceptions based on their names
#
# Revision 1.7  1999/11/29 19:26:59  djs
# Code tidied and moved around. Some redundant code eliminated.
#
# Revision 1.6  1999/11/29 15:26:04  djs
# Marshalling bugfixes.
#
# Revision 1.5  1999/11/26 18:52:06  djs
# Bugfixes and refinements
#
# Revision 1.4  1999/11/23 18:49:26  djs
# Lots of fixes, especially marshalling code
# Added todo list to keep track of issues
#
# Revision 1.3  1999/11/19 20:07:33  djs
# Bugfixes. Added utility functions for operations and attributes
#
# Revision 1.2  1999/11/17 20:37:09  djs
# General util functions
#
# Revision 1.1  1999/11/15 19:10:55  djs
# Added module for utility functions specific to generating skeletons
# Union skeletons working
#

import string

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

from omniidl import idlutil,idltype,idlast

from omniidl_be.cxx import util,types,id,ast,output,cxx

# From http://www-i3.informatik.rwth-aachen.de/funny/babbage.html:
#
# A hotly contested issue among language designers is the method for
# passing parameters to subfunctions. Some advocate "call by name," others
# prefer "call by value." Babbage uses a new method - "call by telephone."
# This is especially effective for long-distance parameter passing.

# Code for marshalling and unmarshalling various data types.

def marshall(to, environment, type, decl, argname, to_where,
             exception = "BAD_PARAM"):
    assert isinstance(type, types.Type)

    d_type = type.deref()

    # If this is an array of base types, the quick marshalling option is used.
    # slice_cast is set to the casting required to cast the variable to a
    # pointer to the beginning of the array. There are 3 possibilities:
    #  1. The variable is a declarator, e.g. it is a member of a struct or a
    #     union. No casting is required. slice_cast = ""
    #  2. The variable is not a declarator and its dimension is > 1,
    #     cast the variable to its array slice pointer.
    #  3. Same as 2 but its dimension == 1, just cast the variable to a pointer
    #     to its base class (because the type's array slice may not be
    #     defined).

    if decl:
        assert isinstance(decl, idlast.Declarator)
        dims = decl.sizes() + type.dims()
        slice_cast = ""
    else:
        dims = type.dims()
        if len(dims) != 1:
            slice_cast = "(" + type.base(environment) + "_slice" + "*)"
        else:
            slice_cast = "(" + d_type.base(environment) + "*)"

    if dims != []:
        n_elements = reduce(lambda x,y:x*y, dims, 1)
        array_marshal_helpers = {
          idltype.tk_octet:     ("omni::ALIGN_1",1),
          idltype.tk_boolean:   ("omni::ALIGN_1",1),
          idltype.tk_short:     ("omni::ALIGN_2",2),
          idltype.tk_long:      ("omni::ALIGN_4",4),
          idltype.tk_ushort:    ("omni::ALIGN_2",2),
          idltype.tk_ulong:     ("omni::ALIGN_4",4),
          idltype.tk_float:     ("omni::ALIGN_4",4),
          idltype.tk_double:    ("omni::ALIGN_8",8),
          idltype.tk_longlong:  ("omni::ALIGN_8",8),
          idltype.tk_ulonglong: ("omni::ALIGN_8",8)
        }
        kind = d_type.type().kind()
        if array_marshal_helpers.has_key(kind):
            (alignment,elmsize) = array_marshal_helpers[kind]
            if alignment != "omni::ALIGN_1":
                if kind == idltype.tk_double:
                    to.out("""
#ifndef OMNI_MIXED_ENDIAN_DOUBLE""")

                to.out("""\
if (! @where@.marshal_byte_swap()) {
  @where@.put_octet_array((_CORBA_Octet*)(@slice_cast@@name@),@num@,@align@);
}
else """,
                       where = to_where,
                       name = argname,
                       slice_cast = slice_cast,
                       num = str(n_elements * elmsize),
                       align = alignment)

                if kind == idltype.tk_double:
                    to.out("""\
#endif""")

                # Do not return here.
                # let the code below to deal with the else block.
            else:
                if kind == idltype.tk_boolean:
                    to.out("""
#if !defined(HAS_Cplusplus_Bool) || (SIZEOF_BOOL == 1)""")

                to.out("@where@.put_octet_array((_CORBA_Octet*)(@slice_cast@@name@),@num@);",
                       where = to_where,
                       name = argname,
                       slice_cast = slice_cast,
                       num = str(n_elements))

                if kind == idltype.tk_boolean:
                    to.out("""\
#else""")
                else:
                    return

        # No quick route, generate iteration loop
        block = cxx.Block(to)
        akind = d_type.type().kind()

        # Valuetype chunked encoding needs to know array length before
        # we marshal it item by item.
        if array_marshal_helpers.has_key(akind):
            to.out("""\
@where@.declareArrayLength(@align@, @num@);""",
                   where = to_where,
                   num = str(n_elements * elmsize),
                   align = alignment)

        elif akind == idltype.tk_char:
            to.out("""\
@where@.declareArrayLength(omni::ALIGN_1, @num@);""",
                   where = to_where,
                   num = str(n_elements))

        elif akind == idltype.tk_longdouble:
            to.out("""\
@where@.declareArrayLength(omni::ALIGN_8, @num@);""",
                   where = to_where,
                   num = str(n_elements * 16))

    loop = cxx.For(to, dims)
    indexing_string = loop.index()
    element_name = argname + indexing_string

    if dims != []:
        type_name = d_type.base(environment)
        if type_name == element_name:
            type_name = d_type.base()
    else:
        type_name = type.base(environment)
        if type_name == element_name:
            type_name = type.base()
            
    bounded = ""
    kind = d_type.type().kind()
    
    if d_type.interface():
        type_name = string.replace(type_name,"_ptr","")
        if isinstance(d_type.type().decl(),idlast.Forward):
            # hack to denote an interface forward declaration
            # kind is used to index the associative array below
            kind = idltype.tk_objref * 1000

    elif d_type.value() or d_type.valuebox():
        if isinstance(d_type.type().decl(),idlast.ValueForward):
            kind = idltype.tk_value * 1000

    elif d_type.string() or d_type.wstring():
        bounded = str(d_type.type().bound())

    if not d_type.is_basic_data_types() and not d_type.enum():
        type_cast = "(const " + type_name + "&) "
    else:
        type_cast = ""

    special_marshal_functions = {
      idltype.tk_boolean:
      "@to_where@.marshalBoolean(@element_name@);",
      idltype.tk_octet:
      "@to_where@.marshalOctet(@element_name@);",
      idltype.tk_char:
      "@to_where@.marshalChar(@element_name@);",
      idltype.tk_wchar:
      "@to_where@.marshalWChar(@element_name@);",
      idltype.tk_string:
      "@to_where@.marshalString(@element_name@,@bounded@);",
      idltype.tk_wstring:
      "@to_where@.marshalWString(@element_name@,@bounded@);",
      idltype.tk_objref:
      "@type@::_marshalObjRef(@element_name@,@to_where@);",
      idltype.tk_TypeCode:
      "::CORBA::TypeCode::marshalTypeCode(@element_name@,@to_where@);",
      idltype.tk_objref * 1000:
      "@type@_Helper::marshalObjRef(@element_name@,@to_where@);",
      idltype.tk_value:
      "@type@::_NP_marshal(@element_name@,@to_where@);",
      idltype.tk_value * 1000:
      "@type@_Helper::marshal(@element_name@,@to_where@);",
      idltype.tk_value_box:
      "@type@::_NP_marshal(@element_name@,@to_where@);",
      idltype.tk_abstract_interface:
      "@type@::_marshalObjRef(@element_name@,@to_where@);",
      idltype.tk_local_interface:
      "@type@::_marshalObjRef(@element_name@,@to_where@);",
      }
    if special_marshal_functions.has_key(kind):
        out_template = special_marshal_functions[kind]
    else:
        out_template = "@type_cast@@element_name@ >>= @to_where@;"

    to.out(out_template,
           to_where = to_where,
           element_name = element_name,
           bounded = bounded,
           type = type_name,
           type_cast = type_cast)
    loop.end()

    if dims != []:
        block.end()
        if kind == idltype.tk_boolean:
            to.out("""\
#endif""")


        
def unmarshall(to, environment, type, decl, name, from_where):
    assert isinstance(type, types.Type)

    d_type = type.deref()

    # If this is an array of base types, the quick marshalling option is used.
    # slice_cast is set to the casting required to cast the variable to a
    # pointer to the beginning of the array. There are 3 possibilities:
    #  1. The variable is a declarator, e.g. it is a member of a struct or a
    #     union. No casting is required. slice_cast = ""
    #  2. The variable is not a declarator and its dimension is > 1,
    #     cast the variable to its array slice pointer.
    #  3. Same as 2 but its dimension == 1, just cast the variable to a pointer
    #     to its base class (because the type's array slice may not be
    #     defined).

    if decl:
        assert isinstance(decl, idlast.Declarator)
        dims = decl.sizes() + type.dims()
        slice_cast = ""
    else:
        dims = type.dims()
        if len(dims) != 1:
            slice_cast = "(" + type.base(environment) + "_slice" + "*)"
        else:
            slice_cast = "(" + d_type.base(environment) + "*)"

    if dims != []:

        n_elements = reduce(lambda x,y:x*y, dims, 1)
        array_unmarshal_helpers = {
          idltype.tk_octet:  ("get_octet_array","(_CORBA_Octet*)"),
          idltype.tk_boolean:("unmarshalArrayBoolean","(_CORBA_Boolean*)"),
          idltype.tk_short:  ("unmarshalArrayShort","(_CORBA_Short*)"),
          idltype.tk_long:   ("unmarshalArrayLong","(_CORBA_Long*)"),
          idltype.tk_ushort: ("unmarshalArrayUShort","(_CORBA_UShort*)"),
          idltype.tk_ulong:  ("unmarshalArrayULong","(_CORBA_ULong*)"),
          idltype.tk_float:  ("unmarshalArrayFloat","(_CORBA_Float*)"),
          idltype.tk_double: ("unmarshalArrayDouble","(_CORBA_Double*)"),
          idltype.tk_longlong:("unmarshalArrayLongLong","(_CORBA_LongLong*)"),
          idltype.tk_ulonglong:("unmarshalArrayULongLong","(_CORBA_ULongLong*)")
          }
        kind = d_type.type().kind()

        if array_unmarshal_helpers.has_key(kind):
            (helper,typecast) = array_unmarshal_helpers[kind]
            to.out("@where@.@helper@(@typecast@(@slice_cast@@name@), @num@);",
                   helper = helper,
                   where = from_where, typecast = typecast,
                   name = name,
                   slice_cast = slice_cast,
                   num = str(n_elements))
            return

        # No quick route, generate iteration loop
        block = cxx.Block(to)

    loop = cxx.For(to, dims)
    indexing_string = loop.index()
    element_name = name + indexing_string
    
    if dims != []:
        type_name = d_type.base(environment)
        if type_name == element_name:
            type_name = d_type.base()
    else:
        type_name = type.base(environment)
        if type_name == element_name:
            type_name = type.base()
        
    bounded = ""
    kind = d_type.type().kind()

    if d_type.interface():
        type_name = string.replace(type_name,"_ptr","")
        if isinstance(d_type.type().decl(),idlast.Forward):
            # hack to denote an interface forward declaration
            # kind is used to index the associative array below
            kind = idltype.tk_objref * 1000

    elif d_type.value() or d_type.valuebox():
        if isinstance(d_type.type().decl(),idlast.ValueForward):
            kind = idltype.tk_value * 1000

    elif d_type.string() or d_type.wstring():
        bounded = str(d_type.type().bound())
        
    special_unmarshal_functions = {
      idltype.tk_boolean:
      "@element_name@ = @where@.unmarshalBoolean();",
      idltype.tk_octet:
      "@element_name@ = @where@.unmarshalOctet();",
      idltype.tk_char:
      "@element_name@ = @where@.unmarshalChar();",
      idltype.tk_wchar:
      "@element_name@ = @where@.unmarshalWChar();",
      idltype.tk_string:
      "@element_name@ = @where@.unmarshalString(@bounded@);",
      idltype.tk_wstring:
      "@element_name@ = @where@.unmarshalWString(@bounded@);",
      idltype.tk_objref:
      "@element_name@ = @type@::_unmarshalObjRef(@where@);",
      idltype.tk_TypeCode:
      "@element_name@ = ::CORBA::TypeCode::unmarshalTypeCode(@where@);",
      idltype.tk_objref * 1000:
      "@element_name@ = @type@_Helper::unmarshalObjRef(@where@);",
      idltype.tk_value:
      "@element_name@ = @type@::_NP_unmarshal(@where@);",
      idltype.tk_value * 1000:
      "@element_name@ = @type@_Helper::unmarshal(@where@);",
      idltype.tk_value_box:
      "@element_name@ = @type@::_NP_unmarshal(@where@);",
      idltype.tk_abstract_interface:
      "@element_name@ = @type@::_unmarshalObjRef(@where@);",
      idltype.tk_local_interface:
      "@element_name@ = @type@::_unmarshalObjRef(@where@);",
      }

    if special_unmarshal_functions.has_key(kind):
        out_template = special_unmarshal_functions[kind]
    else:
        out_template = "(@type@&)@element_name@ <<= @where@;"

    to.out(out_template,
           type = type_name,
           element_name = element_name,
           where = from_where,
           bounded = bounded)

    loop.end()

    if dims != []:
        block.end()


def sort_exceptions(ex):
    # sort the exceptions into lexicographical order
    try:
        return sorted(ex, key = lambda e: e.repoId())

    except NameError:
        def lexicographic(exception_a, exception_b):
            name_a = exception_a.repoId()
            name_b = exception_b.repoId()
            return cmp(name_a, name_b)

        raises = ex[:]
        raises.sort(lexicographic)
        return raises
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.