vbclasses.py :  » Language-Interface » VB-to-Python-Converter » vb2py-0.2 » 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 » Language Interface » VB to Python Converter 
VB to Python Converter » vb2py 0.2 » vbclasses.py
# Created by Leo from: C:\Development\Python22\Lib\site-packages\vb2py\vb2py.leo

"""
Classes which mimic the behaviour of VB classes

- Collection
"""

import vbfunctions

# << VB Classes >> (1 of 12)
class Collection(dict):
  """A Collection Class

  An implementation of Visual Basic Collections.
  This implementation assumes that indexing by integers is rare and
  that memory is a less scarce resource than CPU time.

  Based on original code submitted by Jacob Halln.

  """

  # << Collection Methods >> (1 of 12)
  def __init__(self):
    dict.__init__(self)
    # self.insertOrder is used as the relative index when the collection
    # is treated as an array.
    # It is also used as the dictionary key for entries that have no
    # assigned key. This always works because VB keys can only be strings. 
    self.insertOrder = 1
  # << Collection Methods >> (2 of 12)
  def __setitem__(self, Key, Item):
    if isinstance(Key, int):
      raise TypeError("Index must be a non-numeric string")
    if Key is None:
      Key = self.insertOrder
    dict.__setitem__(self, Key, (Item, self.insertOrder, Key))
    self.insertOrder += 1
  # << Collection Methods >> (3 of 12)
  def __getitem__(self, Key):
    try:
      Key = int(Key)
      if Key < 1:
        raise IndexError
      list = self.values()
      list.sort(self._order)
      return list[Key-1][0]
    except ValueError:
      return dict.__getitem__(self, Key)[0]
  # << Collection Methods >> (4 of 12)
  def __delitem__(self, Key):
    try:
      key = int(Key)
      list = self.values()
      list.sort(self._order)
      _, _, key = list[Key-1]
    except ValueError:
      pass
    dict.__delitem__(self, Key)
  # << Collection Methods >> (5 of 12)
  def __call__(self, Key):
    return self.Item(Key)
  # << Collection Methods >> (6 of 12)
  def __iter__(self):
    lst = self.values()
    lst.sort(self._order)
    return iter([val[0] for val in lst])
  # << Collection Methods >> (7 of 12)
  def _getElement(self, Key):
    if isinstance(Key, int):
      list = self.values()
      list.sort(self._order)
      return list[Key-1]
    else:
      return dict.__getitem__(self, Key)
  # << Collection Methods >> (8 of 12)
  def _order(self, a, b):
    # Equality is impossible
    if a[1] < b[1]:
      return -1
    else:
      return 1
  # << Collection Methods >> (9 of 12)
  def Add(self, Item, Key=None, Before=None, After=None):
    """
    Add's an item with an optional key. The item can also be added
    before or after an existing item. The before/after parameters
    can either be integer indices or keys.
    **kw can contain
    - key
    - before
    - after
    before and after exclude each other
    """
    if Before is None and After is None: 
      self[Key] = Item

    elif Before is not None and After is None:
      _, order, _ = self._getElement(Before)
      for k, entry in self.iteritems():
        if entry[1] >= order:
          dict.__setitem__(self, k, (entry[0], entry[1]+1, k))
      if not isinstance(Key, str):
        Key = self.insertOrder
      dict.__setitem__(self, Key, (Item, order, Key))
      self.insertOrder += 1

    elif After is not None and Before is None:
      _, order, _ = self._getElement(After)
      for k, entry in self.iteritems():
        if entry[1] > order:
          dict.__setitem__(self, k, (entry[0], entry[1]+1, k))
      if not isinstance(Key, str):
        Key = self.insertOrder
      dict.__setitem__(self, Key, (Item, order+1, Key))
      self.insertOrder += 1

    else:
      raise VB2PYCodeError("Can't specify both 'before' and 'after' parameters to Collection.Add")
  # << Collection Methods >> (10 of 12)
  def Count(self):
    """Return the length of the collection"""
    return len(self)
  # << Collection Methods >> (11 of 12)
  def Remove(self, Key):
    """Remove an item from the collection"""
    self.__delitem__(Key)
  # << Collection Methods >> (12 of 12)
  def Item(self, Key):
    """Get an item from the collection"""
    return self.__getitem__(Key)
  # -- end -- << Collection Methods >>    




if __name__ == '__main__':
  # Tests
  c = Collection()
  c['a'] = 'va'
  c['b'] = 'vb'
  print c['a']
  print c[2]
  del c[1]
  print c[1]
# << VB Classes >> (2 of 12)
class Integer(int):
  """Python version of VB's integer"""
# << VB Classes >> (3 of 12)
class Single(float):
  """Python version of VB's Single"""
# << VB Classes >> (4 of 12)
class Double(float):
  """Python version of VB's Double"""
# << VB Classes >> (5 of 12)
class Long(int):
  """Python version of VB's Long"""
# << VB Classes >> (6 of 12)
class Byte(int):
  """Python version of VB's Byte"""
# << VB Classes >> (7 of 12)
class Object(object):
  """Python version of VB's Object"""
# << VB Classes >> (8 of 12)
class Variant(float):
  """Python version of VB's Variant"""
# << VB Classes >> (9 of 12)
class FixedString(str):
  """Python version of VB's fixed length string"""

  def __new__(cls, length):
    """Initialize the string"""
    return " "*length
# << VB Classes >> (10 of 12)
def IsMissing(argument):
  """Check if an argument was omitted from a function call

  Missing arguments default to the VBMissingArgument class so
  we just check if the argument is an instance of this type and
  return true if this is the case.

  """
  try:
    return argument._missing
  except AttributeError:
    return 0
# << VB Classes >> (11 of 12)
class VBArray(list):
  """Represents an array in VB

  This is basically a list but we use the __call__ syntax to
  access indexes of the array

  """

  # << VBArray methods >> (1 of 8)
  def __init__(self, size, init_type=None):
    """Initialize with a size or a low and upper bound"""
    if not isinstance(size, tuple) == 1:
      size = (0, size)
    self._min, self._max = size
    if init_type:
      for i in range(size[0], size[1]+1):
        self.append(init_type())
  # << VBArray methods >> (2 of 8)
  def __call__(self, *args):
    """Index the array"""
    return self.__getitem__(args)
  # << VBArray methods >> (3 of 8)
  def __setitem__(self, index, value):
    """Set an item in the array"""
    if isinstance(index, tuple):
      if len(index) == 1:
        myindex, rest = index[0], ()
      else:
        myindex, rest = index[0], index[1:]
    else:
      myindex, rest = index, ()
    if rest:
      list.__getitem__(self, myindex-self._min).__setitem__(rest, value)
    else:
      list.__setitem__(self, myindex-self._min, value)
  # << VBArray methods >> (4 of 8)
  def __getitem__(self, args):
    """Get an item from the array"""
    if isinstance(args, tuple):
      if len(args) == 1:
        myindex, rest = args[0], ()
      else:
        myindex, rest = args[0], args[1:]
    else:
      myindex, rest = args, ()
    if self._min <= myindex <= self._max:
      if rest:
        return list.__getitem__(self, myindex-self._min).__getitem__(rest)
      else:
        return list.__getitem__(self, myindex-self._min)    
    else:
      raise IndexError("Index '%d' is out of range (%d, %d)" % (myindex, self._min, self._max))
  # << VBArray methods >> (5 of 8)
  def __ubound__(self, dimension=1):
    """Return the upper bound"""
    if dimension <= 0:
      raise ValueError("Invalid dimension for UBound: %s" % dimension)
    elif dimension == 1:
      return self._max
    else:
      return self[self._min].__ubound__(dimension-1)
  # << VBArray methods >> (6 of 8)
  def __lbound__(self, dimension=1):
    """Return the lower bound"""
    if dimension <= 0:
      raise ValueError("Invalid dimension for LBound: %s" % dimension)
    elif dimension == 1:
      return self._min
    else:
      return self[self._min].__lbound__(dimension-1)
  # << VBArray methods >> (7 of 8)
  def __contents__(self, pre=()):
    """Iterate over the contents of the array"""
    idx = 0
    ret = []
    for item in self:
      if isinstance(item, VBArray):
        ret.extend(item.__contents__(pre + (idx,)))
      else:
        ret.append((pre+(idx,), item))
      idx +=1
    return ret
  # << VBArray methods >> (8 of 8)
  def __copyto__(self, other):
    """Copy our values to another array"""
    for index, value in self.__contents__():
      try:
        other.__setitem__(index, value)
      except IndexError:
        pass # Throw away values which aren't in the new range
  # -- end -- << VBArray methods >>
# << VB Classes >> (12 of 12)
import threading

class _VBFiles:
  """A class to control all interfaces to the file system

  This is required since VB accesses files through channel numbers rather than
  file objects. Since a channel number might be an expression that is evaluated at
  runtime we can't do a static conversion.

  The solution used here is to have a global object which everyone interfaces to when
  doing reading and writing to files. This object maintains the list of open channels 
  and marshalls all read and write operations.

  """

  # << VBFiles methods >> (1 of 9)
  def __init__(self):
    """Initialize the file interface"""
    self._channels = {}
    self._lock = threading.Lock()
  # << VBFiles methods >> (2 of 9)
  def openFile(self, channelid, filename, mode):
    """Open a file

    If the channel is already one then close it. There are likely to be some
    race conditions here in multithreaded applications so we use a lock to make
    this entire process atomic.

    """
    self._lock.acquire()
    try:
      try:
        old_file = self._channels[channelid]
      except KeyError:
        pass
      else:
        old_file.close()
      #
      self._channels[channelid] = open(filename, mode)
    finally:
      self._lock.release()
  # << VBFiles methods >> (3 of 9)
  def closeFile(self, channelid=None):
    """Close a file

    TODO - what should the error be if there is no file open?

    """
    if channelid is None:
      for channel in self._channels.keys():
        self.closeFile(channel)
    else:
      self._channels[channelid].close()
      del(self._channels[channelid])
  # << VBFiles methods >> (4 of 9)
  def getInput(self, channelid, number, separators=None, evaloutput=1):
    """Get data from a file

    VB nicely parses the input from files into variables so we have to mimic this
    here. 

    For safety sake we go one character at a time here. TODO: find out how VB does this
    and what the implications of chunking would be in a multithreaded app.

    We use the lock to prevent multiple reads.

    """
    if separators is None:
      separators = ("\n", ",", "\t", "")
    #
    self._lock.acquire()
    try:
      vars = []
      f = self._channels[channelid]
      buffer = ""
      while len(vars) < number:
        char = f.read(1)
        if char in separators:
          if evaloutput:
            # Try to eval it - if we get a syntax error then assume it is a string
            try:
              vars.append(eval(buffer))
            except SyntaxError:
              vars.append(buffer)
          else:
            vars.append(buffer)
          buffer = ""  
        else:
          buffer += char
    finally:
      self._lock.release()
    #  
    if number == 1:
      return vars[0]
    else:
      return vars
  # << VBFiles methods >> (5 of 9)
  def getLineInput(self, channelid, number=1):
    """Get data from a file one line at a time with no parsing"""
    return self.getInput(channelid, number, separators=("\n", ""), evaloutput=0)
  # << VBFiles methods >> (6 of 9)
  def writeText(self, channelid, *args):
    """Write data to the file

    We write with tabs separating the variables that are given in the *args parameter.

    We use the lock to protect this section in multithreaded environments.

    """
    self._lock.acquire()
    try:
      if args:
        self._channels[channelid].write("".join([str(arg) for arg in args]))
      else:
        self._channels[channelid].write("\n")
    finally:
      self._lock.release()
  # << VBFiles methods >> (7 of 9)
  def seekFile(self, channelid, position):
    """Move to the specified point in the given channel"""
    self._channels[channelid].seek(position-1) # VB starts at 1
  # << VBFiles methods >> (8 of 9)
  def getFile(self, channelid):
    """Return the underlying file link to a channel"""
    return self._channels[channelid]
  # << VBFiles methods >> (9 of 9)
  def getChars(self, channelid, length):
    """Return the specified number of characters from a file"""
    return self._channels[channelid].read(length)
  # -- end -- << VBFiles methods >>


VBFiles = _VBFiles()
# -- end -- << VB Classes >>
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.