home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / fnb101.zip / Lib / site-packages / Fnorb / orb / Util.py < prev    next >
Text File  |  1999-06-28  |  12KB  |  480 lines

  1. #!/usr/bin/env python
  2. #############################################################################
  3. # Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999
  4. # All Rights Reserved.
  5. #
  6. # The software contained on this media is the property of the DSTC Pty
  7. # Ltd.  Use of this software is strictly in accordance with the
  8. # license agreement in the accompanying LICENSE.HTML file.  If your
  9. # distribution of this software does not contain a LICENSE.HTML file
  10. # then you have no rights to use this software in any manner and
  11. # should contact DSTC at the address below to determine an appropriate
  12. # licensing arrangement.
  13. #      DSTC Pty Ltd
  14. #      Level 7, GP South
  15. #      Staff House Road
  16. #      University of Queensland
  17. #      St Lucia, 4072
  18. #      Australia
  19. #      Tel: +61 7 3365 4310
  20. #      Fax: +61 7 3365 4311
  21. #      Email: enquiries@dstc.edu.au
  22. # This software is being provided "AS IS" without warranty of any
  23. # kind.  In no event shall DSTC Pty Ltd be liable for damage of any
  24. # kind arising out of or in connection with the use or performance of
  25. # this software.
  26. #
  27. # Project:      Fnorb
  28. # File:         $Source: /units/arch/src/Fnorb/orb/RCS/Util.py,v $
  29. # Version:      @(#)$RCSfile: Util.py,v $ $Revision: 1.15 $
  30. #
  31. #############################################################################
  32. """ Module for miscellaneous implementation dependent definitions! """
  33.  
  34.  
  35. # Standard/built-in modules.
  36. import keyword, new, string, UserList
  37.  
  38. # Fnorb extension modules.
  39. import cdr
  40.  
  41.  
  42. # The first four bytes of EVERY GIOP message header must contain this!
  43. MAGIC = ['G', 'I', 'O', 'P']
  44.  
  45. # The version of the GIOP specification that we are implementing.
  46. GIOP_VERSION_MAJOR = 1
  47. GIOP_VERSION_MINOR = 0
  48.  
  49. # The version of the 'cdr' extension module that we must have.
  50. CDR_VERSION = "1.1"
  51. if CDR_VERSION != cdr.version():
  52.     raise "Incompatible version of the 'cdr' extension module"
  53.  
  54. # Define the byte ordering appropriate for the host architecture.
  55. #
  56. # e.g DEC Alpha - LITTLE_ENDIAN
  57. #     Linux     - LITTLE_ENDIAN
  58. #     Solaris   - BIG_ENDIAN
  59. #
  60. # We get the byte order from the cdr extension module.  This is to try and
  61. # localise any parts of the code that require configuration for specific
  62. # architectures.
  63. HOST_BYTE_ORDER = cdr.host_byte_order()
  64.  
  65. # Byte ordering options for GIOP messages.
  66. BIG_ENDIAN    = 0
  67. LITTLE_ENDIAN = 1
  68.  
  69. # Threading models.
  70. REACTIVE = 0
  71. THREADED = 1
  72.  
  73. # Err, the default size of the thread pool ;^)
  74. DEFAULT_THREAD_POOL_SIZE = 10
  75.  
  76.  
  77. def python_name(name):
  78.     """ Add an underscore prefix to any name that is a Python keyword. """
  79.  
  80.     if keyword.iskeyword(name):
  81.     return '_' + name
  82.  
  83.     return name
  84.  
  85.  
  86. class Union:
  87.     """ Base class for unions. """
  88.  
  89.     def __init__(self, discriminator, value):
  90.     """ Constructor. """
  91.  
  92.     self.d = discriminator
  93.     self.v = value
  94.  
  95.     return
  96.  
  97.     def __getinitargs__(self):
  98.     """ Return the constructor arguments for unpickling. """
  99.  
  100.     return (self.d, self.v)
  101.  
  102.     def __str__(self):
  103.     """ Return a string representation of the union. """
  104.  
  105.     return "%s(%s, %s)" % (self.__class__.__name__,str(self.d),str(self.v))
  106.  
  107.  
  108. class Enum(UserList.UserList):
  109.     """ Base class for enumerations. """
  110.  
  111.     def __init__(self, id, data):
  112.     """ Constructor. """
  113.  
  114.     self._FNORB_ID = id
  115.     self.data = data
  116.  
  117.     return
  118.  
  119.     def __getinitargs__(self):
  120.     """ Return the constructor arguments for unpickling. """
  121.  
  122.     return (self._FNORB_ID, self.data)
  123.  
  124.  
  125. class EnumMember:
  126.     """ Enum member class. """
  127.  
  128.     def __init__(self, name, value):
  129.     """ Constructor. """
  130.  
  131.     self._name = name
  132.     self._value = value
  133.  
  134.     return
  135.  
  136.     def __getinitargs__(self):
  137.     """ Return the constructor arguments for unpickling. """
  138.  
  139.     return (self._name, self._value)
  140.  
  141.     def __cmp__(self, other):
  142.     """ Compare two enums. """
  143.  
  144.     return cmp(self._value, other._value)
  145.  
  146.     def __int__(self):
  147.     """ Return the enum as an 'integer' for array indexing etc. """
  148.  
  149.     return self._value
  150.  
  151.     def __hash__(self):
  152.     return self._value
  153.  
  154.     def __str__(self):
  155.     return self._name
  156.  
  157.     __repr__ = __str__
  158.  
  159.     def name(self):
  160.     return self._name
  161.  
  162.     def value(self):
  163.     return self._value
  164.  
  165.  
  166. class RepositoryId:
  167.     """ CORBA Interface Repository Ids.
  168.  
  169.     An Interface Repository id has three colon-separated parts:-
  170.     
  171.     1) The format of the repository id (currently we only support 'IDL')
  172.     2) The scoped name of the type definition
  173.     3) The version of the type definition
  174.     
  175.     eg:- 'IDL:Module/Interface/Hello:1.0'
  176.     
  177.     has parts:-
  178.  
  179.     1) IDL
  180.     2) Module/Interface/Hello
  181.     3) 1.0
  182.  
  183.     """
  184.     def __init__(self, str_id):
  185.     """ Constructor.
  186.  
  187.     'str_id' is the string representation of a repository id.
  188.  
  189.     """
  190.     # Initialise the instance from the string.
  191.     self._from_string(str_id)
  192.  
  193.     return
  194.  
  195.     def __getinitargs__(self):
  196.     """ Return the constructor arguments for unpickling. """
  197.  
  198.     return (str(self),)
  199.  
  200.     def __str__(self):
  201.     """ Return the string version of the repository id. """
  202.  
  203.     scoped_name = self._scoped_name.join('/')
  204.     return self._format + ':' + scoped_name + ':' + self._version
  205.  
  206.     def format(self):
  207.     """ Return the format.
  208.  
  209.     Currently this is ALWAYS 'IDL'.
  210.  
  211.     """
  212.     return self._format
  213.  
  214.     def scoped_name(self):
  215.     """ Return the scoped name. """
  216.  
  217.     return self._scoped_name
  218.     
  219.     def version(self):
  220.     """ Return the version. """
  221.  
  222.     return self._version
  223.  
  224.     def set_scoped_name(self, scoped_name):
  225.     """ Set the scoped name. """
  226.  
  227.     self._scoped_name = scoped_name
  228.     return
  229.  
  230.     def set_version(self, version):
  231.     """ Set the version. """
  232.  
  233.     self._version = version
  234.     return
  235.  
  236.     #########################################################################
  237.     # Internal methods.
  238.     #########################################################################
  239.  
  240.     def _from_string(self, str_id):
  241.     """ Initialise the repository id from a string.
  242.  
  243.     'str_id' is the string representation of a repository id.
  244.  
  245.     An Interface Repository id has three colon-separated parts:-
  246.     
  247.     1) The format of the repository id (currently we only support 'IDL')
  248.     2) The scoped name of the type definition
  249.     3) The version of the type definition
  250.     
  251.     eg:- 'IDL:Module/Interface/Hello:1.0'
  252.  
  253.     has parts:-
  254.  
  255.     1) IDL
  256.     2) Module/Interface/Hello
  257.     3) 1.0
  258.     
  259.     """
  260.     if len(str_id) == 0:
  261.         raise 'Invalid (empty) Repository Id.'
  262.  
  263.     else:
  264.         [self._format, temp_name, self._version] = string.split(str_id,':')
  265.         if self._format != 'IDL':
  266.         raise 'Invalid Repository Id.', str_id
  267.  
  268.         # Each scope in the type name is delimited by the '/' character.
  269.         temp_components = string.split(temp_name, '/')
  270.  
  271.         # 'Real' scoped names are separated by '::'!
  272.         self._scoped_name = ScopedName(string.join(temp_components, '::'))
  273.  
  274.     return
  275.  
  276.  
  277. class CompoundName:
  278.     """ Compound names.
  279.  
  280.     A compound name is made up of one or more components separated by a 
  281.     given character sequence (string).
  282.  
  283.     This class is an abstract class used to derive classes representing IDL
  284.     scoped names and Python package names.
  285.  
  286.     """
  287.     # The component separator (set in each concrete derived class).
  288.     _SEPARATOR = None
  289.  
  290.     def __init__(self, stringified_name=''):
  291.     """ Constructor.
  292.  
  293.     'stringified_name' is the string representation of the compound name.
  294.  
  295.     """
  296.     # Initialise the compound name from the string.
  297.     self._from_string(stringified_name)
  298.  
  299.     return
  300.  
  301.     def __add__(self, other):
  302.     """ Add two compound names. """
  303.  
  304.     new_name = new.instance(self.__class__, {})
  305.     new_name._components = self._components + other._components
  306.  
  307.     return new_name
  308.  
  309.     def __cmp__(self, other):
  310.     """ Compare two compound names. """
  311.  
  312.     return cmp(self._components, other._components)
  313.  
  314.     def __delitem__(self, i):
  315.     """ Delete the i'th component of the compound name. """
  316.  
  317.     del self._components[i]
  318.     return
  319.  
  320.     def __delslice__(self, i, j):
  321.     """ Delete the slice [i:j]. """
  322.  
  323.     del self._components[i:j]
  324.     return
  325.  
  326.     def __getitem__(self, i):
  327.     """ Get the i'th component of the compound name. """
  328.  
  329.     return self._components[i]
  330.  
  331.     def __getinitargs__(self):
  332.     """ Return the constructor arguments for unpickling. """
  333.  
  334.     return (str(self),)
  335.  
  336.     def __getslice__(self, i, j):
  337.     """ Return a new compound name consisting of the slice [i:j]. """
  338.  
  339.     new_name = new.instance(self.__class__, {})
  340.     new_name._components = self._components[i:j]
  341.  
  342.     return new_name
  343.  
  344.     def __len__(self):
  345.     """ Return the number of components in the compound name! """
  346.  
  347.     return len(self._components)
  348.  
  349.     def __mul__(self, n):
  350.     """ Multiply the compound name! """
  351.  
  352.     new_name = new.instance(self.__class__, {})
  353.     new_name._components = self._components * n
  354.  
  355.     return new_name
  356.  
  357.     def __setitem__(self, i, value):
  358.     """ Set the i'th component of the compound name. """
  359.  
  360.     self._components[i] = value
  361.     return
  362.  
  363.     def __setslice__(self, i, j, other):
  364.     """ Set the slice [i:j]. """
  365.  
  366.     self._components[i:j] = other._components[i:j]
  367.     return
  368.  
  369.     def __str__(self):
  370.     """ Return the string representation of the compound name. """
  371.  
  372.     return string.join(self._components, self._SEPARATOR)
  373.  
  374.     __repr__ = __str__
  375.  
  376.     def append(self, component):
  377.     """ Append onto a compound name. """
  378.  
  379.     self._components.append(component)
  380.     return
  381.  
  382.     def insert(self, i, component):
  383.     """ Insert into a compound name. """
  384.  
  385.     self._components.insert(i, component)
  386.     return
  387.  
  388.     def join(self, sep=' '):
  389.     """ Just like 'string.join' ;^) """
  390.  
  391.     return string.join(self._components, sep)
  392.  
  393.     def pythonise(self):
  394.     """ Fix up any clashes with Python keywords. """
  395.  
  396.     self._components = map(python_name, self._components)
  397.     return
  398.     
  399.     #########################################################################
  400.     # Internal methods.
  401.     #########################################################################
  402.  
  403.     def _from_string(self, stringified_name):
  404.     """ Initialise the compound name from a string. """
  405.  
  406.     # This is because string.split('', self._SEPARATOR) = [''] and not []!
  407.     if len(stringified_name) == 0:
  408.         self._components = []
  409.  
  410.     else:
  411.         self._components = string.split(stringified_name, self._SEPARATOR)
  412.  
  413.     return
  414.  
  415.  
  416. class ScopedName(CompoundName):
  417.     """ CORBA Interface Repository scoped names.
  418.  
  419.     A scoped name uniquely identifies modules, interfaces, constants,
  420.     typedefs, exceptions, attributes and operations within an Interface
  421.     Repository.
  422.  
  423.     A scoped name is a compound name made up of one or more identifiers
  424.     separated by "::".
  425.     
  426.     eg:- 'AModule::AnInterface::SomeContainedObject'
  427.  
  428.     """
  429.     # The component separator.
  430.     _SEPARATOR = '::'
  431.  
  432.  
  433. class PackageName(CompoundName):
  434.     """ Python package names.
  435.  
  436.     A package name is a compound name made up of one or more identifiers
  437.     separated by ".".
  438.     
  439.     eg:- 'Foo.Bar.Baz'
  440.  
  441.     """
  442.     # The component separator.
  443.     _SEPARATOR = '.'
  444.  
  445.  
  446. #############################################################################
  447. # Functions to stringify and unstringify Naming service names.
  448. #############################################################################
  449.  
  450. def _fnorb_name_to_string(name):
  451.     """ Convert a 'real' name into a stringified name! """
  452.  
  453.     components = []
  454.     for component in name:
  455.     components.append(component.id)
  456.     
  457.     # Backslashes are currently used to separate name components.
  458.     return 'name:' + string.join(components, '/')
  459.  
  460. def _fnorb_string_to_name(stringified_name):
  461.     """ Convert a stringified name into a 'real' name! """
  462.  
  463.     # fixme: We do the import here to get around the old circular import
  464.     # problems!
  465.     from Fnorb.cos.naming import CosNaming
  466.  
  467.     # Naming service names are simple lists of 'NameComponent's.
  468.     name = []
  469.  
  470.     # Backslashes are currently used to separate name components.
  471.     components = string.split(stringified_name[5:], '/')
  472.     for component in components:
  473.     name.append(CosNaming.NameComponent(component, ''))
  474.  
  475.     return name
  476.  
  477. #############################################################################
  478.