# -*- Mode: Python; -*-
# Package : omniORBpy
# tcInternal.py Created on: 1999/06/24
# Author : Duncan Grisby (dpg1)
#
# Copyright (C) 1999 AT&T Laboratories Cambridge
#
# This file is part of the omniORBpy library
#
# The omniORBpy library is free software; you can redistribute it
# and/or modify it under the terms of the GNU Lesser General
# Public License as published by the Free Software Foundation;
# either version 2.1 of the License, or (at your option) any later
# version.
#
# This library 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA
#
#
# Description:
# TypeCode internal implementation
# $Id: tcInternal.py,v 1.13.2.11 2007/06/06 17:59:01 dgrisby Exp $
# $Log: tcInternal.py,v $
# Revision 1.13.2.11 2007/06/06 17:59:01 dgrisby
# Allow enums to be used directly in CORBA.TypeCode().
#
# Revision 1.13.2.10 2007/04/26 08:33:38 dgrisby
# Incorrect kind() return for object reference TypeCodes. Thanks
# Andrew Edem.
#
# Revision 1.13.2.9 2006/07/11 13:53:09 dgrisby
# Implement missing TypeCode creation functions.
#
# Revision 1.13.2.8 2006/02/16 22:55:45 dgrisby
# Remove some tab characters that snuck in from a patch.
#
# Revision 1.13.2.7 2006/01/19 17:28:44 dgrisby
# Merge from omnipy2_develop.
#
# Revision 1.13.2.6 2005/11/09 12:33:31 dgrisby
# Support POA LocalObjects.
#
# Revision 1.13.2.5 2005/07/29 11:27:23 dgrisby
# Static map of basic TypeCodes for speed.
#
# Revision 1.13.2.4 2005/01/07 00:22:35 dgrisby
# Big merge from omnipy2_develop.
#
# Revision 1.13.2.3 2003/07/10 22:13:25 dgrisby
# Abstract interface support.
#
# Revision 1.13.2.2 2003/05/20 17:10:26 dgrisby
# Preliminary valuetype support.
#
# Revision 1.13.2.1 2003/03/23 21:51:43 dgrisby
# New omnipy3_develop branch.
#
# Revision 1.10.2.8 2003/03/12 11:17:50 dgrisby
# Any / TypeCode fixes.
#
# Revision 1.10.2.7 2003/03/07 11:56:04 dgrisby
# Missing TypeCode creation functions.
#
# Revision 1.10.2.6 2002/06/11 20:21:31 dgrisby
# Missed out wchar, wstring TypeCodes.
#
# Revision 1.10.2.5 2002/05/27 01:02:37 dgrisby
# Fix bug with scope lookup in generated code. Fix TypeCode clean-up bug.
#
# Revision 1.10.2.4 2002/03/11 15:40:05 dpg1
# _get_interface support, exception minor codes.
#
# Revision 1.10.2.3 2001/05/14 14:49:39 dpg1
# Fix get_compact_typecode() and equivalent()
#
# Revision 1.10.2.2 2001/04/10 11:11:15 dpg1
# TypeCode support and tests for Fixed point.
#
# Revision 1.10.2.1 2000/11/01 15:29:01 dpg1
# Support for forward-declared structs and unions
# RepoIds in indirections are now resolved at the time of use
#
# Revision 1.10 2000/08/21 10:20:19 dpg1
# Merge from omnipy1_develop for 1.1 release
#
# Revision 1.9.2.1 2000/08/07 09:19:24 dpg1
# Long long support
#
# Revision 1.9 2000/01/31 10:51:41 dpg1
# Fix to exception throwing.
#
# Revision 1.8 1999/11/02 10:38:31 dpg1
# Last bug wasn't quite fixed.
#
# Revision 1.7 1999/11/01 20:59:42 dpg1
# Fixed bug in insertIndirections() if the same node is indirected to
# more than once.
#
# Revision 1.6 1999/09/24 09:22:00 dpg1
# Added copyright notices.
#
# Revision 1.5 1999/09/20 15:11:45 dpg1
# Bug in insertIndirections() fixed.
#
# Revision 1.4 1999/09/13 14:52:27 dpg1
# TypeCode equivalence.
#
# Revision 1.3 1999/07/29 14:17:18 dpg1
# TypeCode creation interface.
#
# Revision 1.2 1999/07/19 15:48:40 dpg1
# All sorts of fixes.
#
# Revision 1.1 1999/06/24 15:23:28 dpg1
# Initial revision
#
import omniORB, CORBA
import types
# The TypeCode implementation is based upon descriptors consisting of
# Python tuples, as used by the marshalling code. Although the public
# interface to TypeCodes presents a graph of connected TypeCode
# objects, the graph is actually only fully-stored by the descriptor
# tuple. A root TypeCode object has a reference to the top of the
# descriptor tuple. Non-root TypeCode objects are only created when
# requested.
#
# Recursive descriptors pose a problem for Python's garbage collector.
# To ensure they are properly collected, all non-root TypeCode objects
# keep a reference to the root TypeCode object. The root TypeCode is
# therefore only deleted once all "views" of the TypeCode have gone.
# When the root TypeCode object is deleted, it recursively descends
# its descriptor, and removes any indirections it finds. All loops are
# thus removed from the descriptor, making it a candidate for
# collection.
#
# This approach means that the descriptor becomes invalid once the
# root TypeCode object is deleted, even if there are other active
# references to the descriptor. BEWARE!
# Kinds as numbers:
tv_null = 0
tv_void = 1
tv_short = 2
tv_long = 3
tv_ushort = 4
tv_ulong = 5
tv_float = 6
tv_double = 7
tv_boolean = 8
tv_char = 9
tv_octet = 10
tv_any = 11
tv_TypeCode = 12
tv_Principal = 13
tv_objref = 14
tv_struct = 15
tv_union = 16
tv_enum = 17
tv_string = 18
tv_sequence = 19
tv_array = 20
tv_alias = 21
tv_except = 22
tv_longlong = 23
tv_ulonglong = 24
tv_longdouble = 25
tv_wchar = 26
tv_wstring = 27
tv_fixed = 28
tv_value = 29
tv_value_box = 30
tv_native = 31
tv_abstract_interface = 32
tv_local_interface = 33
tv__indirect = -1
# Create a TypeCode given a class or a repoId
def typeCodeFromClassOrRepoId(t):
try:
t = t._NP_RepositoryId
except AttributeError:
pass
if type(t) is not types.StringType:
raise TypeError("Argument must be CORBA class or repository id.")
d = omniORB.findType(t)
if d is None:
raise TypeError("Unknown CORBA type.")
return createTypeCode(d)
# Implementations of public ORB TypeCode creation functions
def createStructTC(id, name, members):
dlist = [tv_struct, None, id, name]
mnames = []
for m in members:
mnames.append(m.name)
dlist.append(m.name)
dlist.append(m.type._d)
str = omniORB.createUnknownStruct(id, mnames)
dlist[1] = str
d = tuple(dlist)
return createTypeCode(d)
def createUnionTC(id, name, discriminator_type, members):
mlist = []
count = 0
defused = -1
mmap = {}
for m in members:
val = m.label.value()
if m.label.typecode().kind() == CORBA.tk_octet and val == 0:
val = -1
defused = count
tup = (val, m.name, m.type._d)
if defused != count: mmap[val] = tup
mlist.append(tup)
count = count + 1
union = omniORB.createUnknownUnion(id, defused, mlist)
if defused >= 0:
default = mlist[defused]
else:
default = None
d = (tv_union, union, id, name, discriminator_type._k._v,
defused, tuple(mlist), default, mmap)
return createTypeCode(d)
def createEnumTC(id, name, members):
mlist = []
count = 0
for m in members:
mlist.append(omniORB.EnumItem(m, count))
count = count + 1
d = (tv_enum, id, name, tuple(mlist))
return createTypeCode(d)
def createAliasTC(id, name, original_type):
d = (tv_alias, id, name, original_type._d)
return createTypeCode(d)
def createExceptionTC(id, name, members):
dlist = [tv_except, None, id, name]
mnames = []
for m in members:
mnames.append(m.name)
dlist.append(m.name)
dlist.append(m.type._d)
exc = omniORB.createUnknownException(id, mnames)
dlist[1] = exc
d = tuple(dlist)
return createTypeCode(d)
def createInterfaceTC(id, name):
d = (tv_objref, id, name)
return createTypeCode(d)
def createStringTC(bound):
d = (tv_string, bound)
return createTypeCode(d)
def createWStringTC(bound):
d = (tv_wstring, bound)
return createTypeCode(d)
def createFixedTC(digits, scale):
if digits < 1 or digits > 31 or scale > digits:
raise CORBA.BAD_PARAM(omniORB.BAD_PARAM_InvalidFixedPointLimits,
CORBA.COMPLETED_NO)
d = (tv_fixed, digits, scale)
return createTypeCode(d)
def createSequenceTC(bound, element_type):
d = (tv_sequence, element_type._d, bound)
return createTypeCode(d)
def createArrayTC(length, element_type):
d = (tv_array, element_type._d, length)
return createTypeCode(d)
def createRecursiveTC(id):
class recursivePlaceHolder: pass
recursivePlaceHolder._d = (tv__indirect, [id])
return recursivePlaceHolder()
def createValueTC(id, name, modifier, base, members):
base_desc = base._d
if modifier == CORBA.VM_TRUNCATABLE:
if base_desc == tv_null:
raise CORBA.BAD_PARAM(omniORB.BAD_PARAM_InvalidTypeCode,
CORBA.COMPLETED_NO)
base_ids = base_desc[5]
if base_ids is None:
base_ids = (id, base_desc[2])
else:
base_ids = (id,) + base_ids
else:
base_ids = None
dlist = [tv_value, omniORB.createUnknownValue(id, base_desc),
id, name, modifier, base_ids, base_desc]
for m in members:
dlist.append(m.name)
dlist.append(m.type._d)
dlist.append(m.access)
return createTypeCode(tuple(dlist))
def createValueBoxTC(id, name, boxed_type):
d = (tv_value_box, omniORB.createUnknownValue(id, tv_null),
id, name, boxed_type._d)
return createTypeCode(d)
def createAbstractInterfaceTC(id, name):
d = (tv_abstract_interface, id, name)
return createTypeCode(d)
def createLocalInterfaceTC(id, name):
d = (tv_local_interface, id, name)
return createTypeCode(d)
# Function to create a TypeCode object given a descriptor. Returns a
# static (stub generated) TypeCode object if possible.
typeCodeMapping = omniORB.typeCodeMapping
def createTypeCode(d, parent=None):
try:
r = basicTypeCodes.get(d)
if r is not None:
return r
except TypeError:
# Happens if d contains a mutable object
pass
if type(d) is not types.TupleType:
raise CORBA.INTERNAL()
k = d[0]
if k == tv_string: return TypeCode_string(d)
elif k == tv_wstring: return TypeCode_wstring(d)
elif k == tv_fixed: return TypeCode_fixed(d)
elif k in [ tv_objref, tv_abstract_interface, tv_local_interface ]:
tc = typeCodeMapping.get(d[1])
if tc is None:
tc = TypeCode_objref(d)
return tc
elif k == tv_struct:
tc = typeCodeMapping.get(d[2])
if tc is None:
tc = TypeCode_struct(d, parent)
return tc
elif k == tv_union:
tc = typeCodeMapping.get(d[2])
if tc is None:
tc = TypeCode_union(d, parent)
return tc
elif k == tv_enum:
tc = typeCodeMapping.get(d[1])
if tc is None:
tc = TypeCode_enum(d)
return tc
elif k == tv_sequence: return TypeCode_sequence(d, parent)
elif k == tv_array: return TypeCode_array(d, parent)
elif k == tv_alias:
tc = typeCodeMapping.get(d[1])
if tc is None:
tc = TypeCode_alias(d, parent)
return tc
elif k == tv_except:
tc = typeCodeMapping.get(d[2])
if tc is None:
tc = TypeCode_except(d, parent)
return tc
elif k == tv_value:
tc = typeCodeMapping.get(d[2])
if tc is None:
tc = TypeCode_value(d, parent)
return tc
elif k == tv_value_box:
tc = typeCodeMapping.get(d[2])
if tc is None:
tc = TypeCode_value_box(d, parent)
return tc
elif k == tv__indirect:
if type(d[1][0]) == types.StringType:
nd = omniORB.findType(d[1][0])
if nd is None:
raise CORBA.BAD_TYPECODE(omniORB.BAD_TYPECODE_InvalidIndirection,
CORBA.COMPLETED_NO)
d[1][0] = nd
return createTypeCode(d[1][0], parent)
raise CORBA.INTERNAL()
# TypeCode base interface
class TypeCode_base (CORBA.TypeCode):
def __init__(self):
self._d = 0
self._k = CORBA.tk_null
def equal(self, tc):
try:
if self._d == tc._d: return CORBA.TRUE
else: return CORBA.FALSE
except AttributeError:
raise CORBA.BAD_PARAM(omniORB.BAD_PARAM_WrongPythonType,
CORBA.COMPLETED_NO)
def equivalent(self, tc):
return self.equal(tc)
def get_compact_typecode(self):
return self
def kind(self):
return self._k
# Operations which are only available for some kinds:
def id(self): raise CORBA.TypeCode.BadKind()
def name(self): raise CORBA.TypeCode.BadKind()
def member_count(self): raise CORBA.TypeCode.BadKind()
def member_name(self, index): raise CORBA.TypeCode.BadKind()
def member_type(self, index): raise CORBA.TypeCode.BadKind()
def member_label(self, index): raise CORBA.TypeCode.BadKind()
def discriminator_type(self): raise CORBA.TypeCode.BadKind()
def default_index(self): raise CORBA.TypeCode.BadKind()
def length(self): raise CORBA.TypeCode.BadKind()
def content_type(self): raise CORBA.TypeCode.BadKind()
def fixed_digits(self): raise CORBA.TypeCode.BadKind()
def fixed_scale(self): raise CORBA.TypeCode.BadKind()
def member_visibility(self, index): raise CORBA.TypeCode.BadKind()
def type_modifier(self): raise CORBA.TypeCode.BadKind()
def concrete_base_type(self): raise CORBA.TypeCode.BadKind()
# Class for short, long, ushort, ulong, float, double, boolean, char,
# octet, any, TypeCode, Principal, longlong, ulonglong, longdouble:
class TypeCode_empty (TypeCode_base):
def __init__(self, desc):
if type(desc) is not types.IntType: raise CORBA.INTERNAL()
if desc not in [ tv_null, tv_void, tv_short, tv_long, tv_ushort,
tv_ulong, tv_float, tv_double, tv_boolean, tv_char,
tv_octet, tv_any, tv_TypeCode, tv_Principal,
tv_longlong, tv_ulonglong, tv_longdouble, tv_wchar ]:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.TCKind._item(desc)
def __repr__(self):
return "CORBA.TC" + str(self._k)[8:]
# string:
class TypeCode_string (TypeCode_base):
def __init__(self, desc):
if type(desc) is not types.TupleType or \
desc[0] != tv_string:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_string
def length(self):
return self._d[1]
def __repr__(self):
if self._d[1] == 0:
return "CORBA.TC_string"
else:
return "orb.create_string_tc(bound=%d)" % self._d[1]
# wstring:
class TypeCode_wstring (TypeCode_base):
def __init__(self, desc):
if type(desc) is not types.TupleType or \
desc[0] != tv_wstring:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_wstring
def length(self):
return self._d[1]
def __repr__(self):
if self._d[1] == 0:
return "CORBA.TC_wstring"
else:
return "orb.create_wstring_tc(bound=%d)" % self._d[1]
# fixed:
class TypeCode_fixed (TypeCode_base):
def __init__(self, desc):
if type(desc) is not types.TupleType or \
desc[0] != tv_fixed:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_fixed
def fixed_digits(self):
return self._d[1]
def fixed_scale(self):
return self._d[2]
def __repr__(self):
return "orb.create_fixed_tc(digits=%d,scale=%d)" % (
self.fixed_digits(), self.fixed_scale())
# objref:
class TypeCode_objref (TypeCode_base):
def __init__(self, desc):
if type(desc) is not types.TupleType or \
desc[0] not in [ tv_objref,
tv_abstract_interface,
tv_local_interface ]:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.TCKind._items[desc[0]]
def id(self):
if self._d[1] is not None:
return self._d[1]
else:
return ""
def name(self): return self._d[2]
def __repr__(self):
return 'CORBA.TypeCode("%s")' % self.id()
# struct:
class TypeCode_struct (TypeCode_base):
def __init__(self, desc, parent):
if type(desc) is not types.TupleType or \
desc[0] != tv_struct:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_struct
self._p = parent
def __del__(self):
if self._p is None and removeIndirections is not None:
removeIndirections(self._d)
def equivalent(self, tc):
return equivalentDescriptors(self._d, tc._d)
def get_compact_typecode(self):
return TypeCode_struct(getCompactDescriptor(self._d), None)
def id(self): return self._d[2]
def name(self): return self._d[3]
def member_count(self): return (len(self._d) - 4) / 2
def member_name(self, index):
off = index * 2 + 4
if index < 0 or off >= len(self._d): raise CORBA.TypeCode.Bounds()
return self._d[off]
def member_type(self, index):
off = index * 2 + 5
if index < 0 or off >= len(self._d): raise CORBA.TypeCode.Bounds()
if self._p is None and removeIndirections is not None:
return createTypeCode(self._d[off], self)
else:
return createTypeCode(self._d[off], self._p)
def __repr__(self):
return 'CORBA.TypeCode("%s")' % self.id()
# union:
class TypeCode_union (TypeCode_base):
def __init__(self, desc, parent):
if type(desc) is not types.TupleType or \
desc[0] != tv_union:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_union
self._p = parent
def __del__(self):
if self._p is None and removeIndirections is not None:
removeIndirections(self._d)
def equivalent(self, tc):
return equivalentDescriptors(self._d, tc._d)
def get_compact_typecode(self):
return TypeCode_union(getCompactDescriptor(self._d), None)
def id(self): return self._d[2]
def name(self): return self._d[3]
def member_count(self): return len(self._d[6])
def member_name(self, index):
if index < 0 or index >= len(self._d[6]): raise CORBA.TypeCode.Bounds()
return self._d[6][index][1]
def member_type(self, index):
if index < 0 or index >= len(self._d[6]): raise CORBA.TypeCode.Bounds()
if self._p is None and removeIndirections is not None:
return createTypeCode(self._d[6][index][2], self)
else:
return createTypeCode(self._d[6][index][2], self._p)
def member_label(self, index):
if index < 0 or index >= len(self._d[6]): raise CORBA.TypeCode.Bounds()
if index == self._d[5]: return CORBA.Any(CORBA._tc_octet, 0)
return CORBA.Any(createTypeCode(self._d[4]), self._d[6][index][0])
def discriminator_type(self): return createTypeCode(self._d[4])
def default_index(self):
if self._d[5] >= 0: return self._d[5]
return -1
def __repr__(self):
return 'CORBA.TypeCode("%s")' % self.id()
# enum:
class TypeCode_enum (TypeCode_base):
def __init__(self, desc):
if type(desc) is not types.TupleType or \
desc[0] != tv_enum:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_enum
def equivalent(self, tc):
return equivalentDescriptors(self._d, tc._d)
def get_compact_typecode(self):
return TypeCode_enum(getCompactDescriptor(self._d))
def id(self): return self._d[1]
def name(self): return self._d[2]
def member_count(self): return len(self._d[3])
def member_name(self, index):
if index < 0 or index >= len(self._d[3]): raise CORBA.TypeCode.Bounds()
return self._d[3][index]._n
def __repr__(self):
return 'CORBA.TypeCode("%s")' % self.id()
# sequence:
class TypeCode_sequence (TypeCode_base):
def __init__(self, desc, parent):
if type(desc) is not types.TupleType or \
desc[0] != tv_sequence:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_sequence
self._p = parent
def __del__(self):
if self._p is None and removeIndirections is not None:
removeIndirections(self._d)
def equivalent(self, tc):
return equivalentDescriptors(self._d, tc._d)
def get_compact_typecode(self):
return TypeCode_sequence(getCompactDescriptor(self._d), None)
def length(self): return self._d[2]
def content_type(self):
if self._p is None and removeIndirections is not None:
return createTypeCode(self._d[1], self)
else:
return createTypeCode(self._d[1], self._p)
def __repr__(self):
return "orb.create_sequence_tc(bound=%d, element_type=%s)" % (
self.length(), repr(self.content_type()))
# array:
class TypeCode_array (TypeCode_base):
def __init__(self, desc, parent):
if type(desc) is not types.TupleType or \
desc[0] != tv_array:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_array
self._p = parent
def __del__(self):
if self._p is None and removeIndirections is not None:
removeIndirections(self._d)
def equivalent(self, tc):
return equivalentDescriptors(self._d, tc._d)
def get_compact_typecode(self):
return TypeCode_sequence(getCompactDescriptor(self._d), None)
def length(self): return self._d[2]
def content_type(self): return createTypeCode(self._d[1])
def __repr__(self):
return "orb.create_array_tc(length=%d, element_type=%s)" % (
self.length(), repr(self.content_type()))
# alias:
class TypeCode_alias (TypeCode_base):
def __init__(self, desc, parent):
if type(desc) is not types.TupleType or \
desc[0] != tv_alias:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_alias
self._p = parent
def __del__(self):
if self._p is None and removeIndirections is not None:
removeIndirections(self._d)
def equivalent(self, tc):
return equivalentDescriptors(self._d, tc._d)
def get_compact_typecode(self):
return TypeCode_alias(getCompactDescriptor(self._d), None)
def id(self): return self._d[1]
def name(self): return self._d[2]
def content_type(self): return createTypeCode(self._d[3])
def __repr__(self):
return 'CORBA.TypeCode("%s")' % self.id()
# except:
class TypeCode_except (TypeCode_base):
def __init__(self, desc, parent):
if type(desc) is not types.TupleType or \
desc[0] != tv_except:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_except
self._p = parent
def __del__(self):
if self._p is None and removeIndirections is not None:
removeIndirections(self._d)
def equivalent(self, tc):
return equivalentDescriptors(self._d, tc._d)
def get_compact_typecode(self):
return TypeCode_except(getCompactDescriptor(self._d), None)
def id(self): return self._d[2]
def name(self): return self._d[3]
def member_count(self): return (len(self._d) - 4) / 2
def member_name(self, index):
off = index * 2 + 4
if index < 0 or off >= len(self._d): raise CORBA.TypeCode.Bounds()
return self._d[off]
def member_type(self, index):
off = index * 2 + 5
if index < 0 or off >= len(self._d): raise CORBA.TypeCode.Bounds()
if self._p is None and removeIndirections is not None:
return createTypeCode(self._d[off], self)
else:
return createTypeCode(self._d[off], self._p)
def __repr__(self):
return 'CORBA.TypeCode("%s")' % self.id()
# value:
class TypeCode_value (TypeCode_base):
def __init__(self, desc, parent):
if type(desc) is not types.TupleType or \
desc[0] != tv_value:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_value
self._p = parent
def __del__(self):
if self._p is None and removeIndirections is not None:
removeIndirections(self._d)
def equivalent(self, tc):
return equivalentDescriptors(self._d, tc._d)
def get_compact_typecode(self):
return TypeCode_value(getCompactDescriptor(self._d), None)
def id(self): return self._d[2]
def name(self): return self._d[3]
def member_count(self): return (len(self._d) - 7) / 3
def member_name(self, index):
off = index * 3 + 7
if index < 0 or off >= len(self._d): raise CORBA.TypeCode.Bounds()
return self._d[off]
def member_type(self, index):
off = index * 3 + 8
if index < 0 or off >= len(self._d): raise CORBA.TypeCode.Bounds()
if self._p is None and removeIndirections is not None:
return createTypeCode(self._d[off], self)
else:
return createTypeCode(self._d[off], self._p)
def member_visibility(self, index):
off = index * 3 + 9
if index < 0 or off >= len(self._d): raise CORBA.TypeCode.Bounds()
return self._d[off]
def type_modifier(self):
return self._d[4]
def concrete_base_type(self):
if self._d[6] == tv_null:
return None
else:
return createTypeCode(self._d[6], self._p)
def __repr__(self):
return 'CORBA.TypeCode("%s")' % self.id()
# valuebox:
class TypeCode_value_box (TypeCode_base):
def __init__(self, desc, parent):
if type(desc) is not types.TupleType or \
desc[0] != tv_value_box:
raise CORBA.INTERNAL()
self._d = desc
self._k = CORBA.tk_value_box
self._p = parent
def __del__(self):
if self._p is None and removeIndirections is not None:
removeIndirections(self._d)
def equivalent(self, tc):
return equivalentDescriptors(self._d, tc._d)
def get_compact_typecode(self):
return TypeCode_alias(getCompactDescriptor(self._d), None)
def id(self): return self._d[2]
def name(self): return self._d[3]
def content_type(self): return createTypeCode(self._d[4])
def __repr__(self):
return 'CORBA.TypeCode("%s")' % self.id()
# Map of pre-created basic TypeCodes
basicTypeCodes = {
tv_null: TypeCode_empty(tv_null),
tv_void: TypeCode_empty(tv_void),
tv_short: TypeCode_empty(tv_short),
tv_long: TypeCode_empty(tv_long),
tv_ushort: TypeCode_empty(tv_ushort),
tv_ulong: TypeCode_empty(tv_ulong),
tv_float: TypeCode_empty(tv_float),
tv_double: TypeCode_empty(tv_double),
tv_boolean: TypeCode_empty(tv_boolean),
tv_char: TypeCode_empty(tv_char),
tv_octet: TypeCode_empty(tv_octet),
tv_any: TypeCode_empty(tv_any),
tv_TypeCode: TypeCode_empty(tv_TypeCode),
tv_Principal: TypeCode_empty(tv_Principal),
tv_longlong: TypeCode_empty(tv_longlong),
tv_ulonglong: TypeCode_empty(tv_ulonglong),
tv_longdouble:TypeCode_empty(tv_longdouble),
tv_wchar: TypeCode_empty(tv_wchar),
(tv_string, 0): TypeCode_string ((tv_string, 0)),
(tv_wstring,0): TypeCode_wstring((tv_wstring, 0)),
}
# Functions to test descriptor equivalence
def equivalentDescriptors(a, b, seen=None, a_ids=None, b_ids=None):
if seen is None:
seen = {}
a_ids = {}
b_ids = {}
try:
if a == b: return 1
# If they don't trivially match, they must be tuples:
if type(a) is not types.TupleType or type(b) is not types.TupleType:
return 0
# Follow aliases and indirections
while (type(a) is types.TupleType and
(a[0] == tv_alias or a[0] == tv__indirect)):
if a[0] == tv_alias:
if a[1] != "": a_ids[a[1]] = a
a = a[3]
else:
if type(a[1][0]) is types.StringType:
a = a_ids[a[1][0]]
else:
a = a[1][0]
while (type(b) is types.TupleType and
(b[0] == tv_alias or b[0] == tv__indirect)):
if b[0] == tv_alias:
if b[1] != "": b_ids[b[1]] = b
b = b[3]
else:
if type(b[1][0]) is types.StringType:
b = b_ids[b[1][0]]
else:
b = b[1][0]
# Re-do the trivial checks on the underlying types.
if a == b: return 1
if type(a) is not types.TupleType or type(b) is not types.TupleType:
return 0
# Handle cycles
if seen.has_key((id(a),id(b))):
return 1
seen[id(a),id(b)] = None
# Must be same kind
if a[0] != b[0]:
return 0
if a[0] == tv_struct:
# id
if a[2] != "": a_ids[a[2]] = a
if b[2] != "": b_ids[b[2]] = b
if a[2] != "" and b[2] != "":
if a[2] == b[2]:
return 1
else:
return 0
# members:
if len(a) != len(b):
return 0
for i in range(4, len(a), 2):
# Member type
if not equivalentDescriptors(a[i+1], b[i+1],
seen, a_ids, b_ids):
return 0
return 1
elif a[0] == tv_union:
# id
if a[2] != "": a_ids[a[2]] = a
if b[2] != "": b_ids[b[2]] = b
if a[2] != "" and b[2] != "":
if a[2] == b[2]:
return 1
else:
return 0
# discriminant type
if not equivalentDescriptors(a[4], b[4], seen, a_ids, b_ids):
return 0
# default index
if a[5] != b[5]:
return 0
# Members
if len(a[6]) != len(b[6]):
return 0
for i in range(len(a[6])):
# Member label
if a[6][i][0] != b[6][i][0]:
return 0
# Member descriptor
if not equivalentDescriptors(a[6][i][2], b[6][i][2],
seen, a_ids, b_ids):
return 0
return 1
elif a[0] == tv_enum:
# id
if a[1] != "": a_ids[a[1]] = a
if b[1] != "": b_ids[b[1]] = b
if a[1] != "" and b[1] != "":
if a[1] == b[1]:
return 1
else:
return 0
# Members
if len(a[3]) != len(b[3]):
return 0
return 1
elif a[0] == tv_sequence:
# Bound
if a[2] != b[2]:
return 0
# Type
return equivalentDescriptors(a[1], b[1], seen, a_ids, b_ids)
elif a[0] == tv_array:
# Length
if a[2] != b[2]:
return 0
# Type
return equivalentDescriptors(a[1], b[1], seen, a_ids, b_ids)
elif a[0] == tv_except:
# id
if a[2] != "": a_ids[a[2]] = a
if b[2] != "": b_ids[b[2]] = b
if a[2] != "" and b[2] != "":
if a[2] == b[2]:
return 1
else:
return 0
# members:
if len(a) != len(b):
return 0
for i in range(4, len(self._d), 2):
# Member type
if not equivalentDescriptors(a[i+1], b[i+1],
seen, a_ids, b_ids):
return 0
return 1
elif a[0] == tv_value:
# id
if a[2] != "": a_ids[a[2]] = a
if b[2] != "": b_ids[b[2]] = b
if a[2] != "" and b[2] != "":
if a[2] == b[2]:
return 1
else:
return 0
# members
if len(a) != len(b):
return 0
for i in range(7, len(a), 3):
# Access spec
if a[i+2] != b[i+2]:
return 0
if not equivalentDescriptors(a[i+1], b[i+1],
seen, a_ids, b_ids):
return 0
return 1
elif a[0] == tv_value_box:
# id
if a[2] != "": a_ids[a[2]] = a
if b[2] != "": b_ids[b[2]] = b
if a[2] != "" and b[2] != "":
if a[2] == b[2]:
return 1
else:
return 0
# Boxed type
if equivalentDescriptors(a[4], b[4], seen, a_ids, b_ids):
return 1
else:
return 0
return 0
except AttributeError:
raise CORBA.BAD_PARAM(BAD_PARAM_WrongPythonType, CORBA.COMPLETED_NO)
# Functions to compact descriptors:
def getCompactDescriptor(d):
seen = {}
ind = []
r = r_getCompactDescriptor(d, seen, ind)
# Fix up indirections:
for i in ind:
try:
if (type(i[0]) is types.StringType):
i[0] = seen[i[0]]
else:
i[0] = seen[id(i[0])]
except KeyError:
raise CORBA.BAD_TYPECODE(BAD_TYPECODE_InvalidIndirection,
CORBA.COMPLETED_NO)
return r
def r_getCompactDescriptor(d, seen, ind):
if type(d) is types.TupleType:
k = d[0]
else:
k = d
if k == tv_short: r = d
elif k == tv_long: r = d
elif k == tv_ushort: r = d
elif k == tv_ulong: r = d
elif k == tv_float: r = d
elif k == tv_double: r = d
elif k == tv_boolean: r = d
elif k == tv_char: r = d
elif k == tv_octet: r = d
elif k == tv_any: r = d
elif k == tv_TypeCode: r = d
elif k == tv_Principal: r = d
elif k == tv_string: r = d
elif k == tv_objref: r = d
elif k == tv_longlong: r = d
elif k == tv_ulonglong: r = d
elif k == tv_longdouble:r = d
elif k == tv_struct:
c = list(d)
c[3] = ""
for i in range(4, len(c), 2):
c[i] = ""
c[i+1] = r_getCompactDescriptor(d[i+1], seen, ind)
r = tuple(c)
seen[d[2]] = r
seen[id(d)] = r
elif k == tv_union:
c = list(d)
c[3] = ""
c[4] = r_getCompactDescriptor(d[4], seen, ind)
m = []
for u in d[6]:
m.append((u[0], "", r_getCompactDescriptor(u[2], seen, ind)))
c[6] = tuple(m)
if d[7] is not None:
c[7] = (d[7][0], "", r_getCompactDescriptor(d[7][2], seen, ind))
r = tuple(c)
seen[d[2]] = r
seen[id(d)] = r
elif k == tv_enum:
m = []
for e in d[3]:
m.append(omniORB.AnonymousEnumItem(e._v))
r = (k, d[1], "", tuple(m))
elif k == tv_sequence:
r = (k, r_getCompactDescriptor(d[1], seen, ind), d[2])
elif k == tv_array:
r = (k, r_getCompactDescriptor(d[1], seen, ind), d[2])
elif k == tv_alias:
r = (k, d[1], "", r_getCompactDescriptor(d[3], seen, ind))
elif k == tv_except:
c = list(d)
c[3] = ""
for i in range(4, len(c), 2):
c[i] = ""
c[i+1] = r_getCompactDescriptor(d[i+1], seen, ind)
r = tuple(c)
elif k == tv_value:
c = list(d)
c[3] = ""
for i in range(7, len(c), 3):
c[i] = ""
c[i+1] = r_getCompactDescriptor(d[i+1], seen, ind)
r = tuple(c)
seen[d[2]] = r
seen[id(d)] = r
elif k == tv_value_box:
c = list(d)
c[3] = ""
c[4] = r_getCompactDescriptor(d[4], seen, ind)
r = tuple(c)
seen[d[2]] = r
seen[id(d)] = r
elif k == tv_abstract_interface:
r = d
elif k == tv_local_interface:
r = d
elif k == tv__indirect:
l = [d[1][0]]
ind.append(l)
r = (k, l)
else: raise CORBA.INTERNAL()
return r
# Function to remove indirections from a descriptor, so it can be
# collected by Python's reference counting garbage collector. Not
# strictly necessary now Python has a cycle collector, but it does no
# harm.
def removeIndirections(desc):
if type(desc) is not types.TupleType: return
k = desc[0]
if k == tv_struct:
for i in range(5, len(desc), 2):
removeIndirections(desc[i])
elif k == tv_union:
for t in desc[6]:
removeIndirections(t[2])
if desc[7] is not None:
removeIndirections(desc[7][2])
elif k == tv_sequence:
removeIndirections(desc[1])
elif k == tv_array:
removeIndirections(desc[1])
elif k == tv_alias:
removeIndirections(desc[3])
elif k == tv_except:
for i in range(5, len(desc), 2):
removeIndirections(desc[i])
elif k == tv_value:
for i in range(8, len(desc), 3):
removeIndirections(desc[i])
elif k == tv__indirect:
desc[1][0] = None
syntax highlighted by Code2HTML, v. 0.9.1