|
@@ -1,406 +0,0 @@
|
|
|
-import ctypes, os, sys
|
|
|
-from ctypes import *
|
|
|
-
|
|
|
-_int_types = (c_int16, c_int32)
|
|
|
-if hasattr(ctypes, "c_int64"):
|
|
|
- # Some builds of ctypes apparently do not have c_int64
|
|
|
- # defined; it's a pretty good bet that these builds do not
|
|
|
- # have 64-bit pointers.
|
|
|
- _int_types += (c_int64,)
|
|
|
-for t in _int_types:
|
|
|
- if sizeof(t) == sizeof(c_size_t):
|
|
|
- c_ptrdiff_t = t
|
|
|
-del t
|
|
|
-del _int_types
|
|
|
-
|
|
|
-
|
|
|
-class c_void(Structure):
|
|
|
- # c_void_p is a buggy return type, converting to int, so
|
|
|
- # POINTER(None) == c_void_p is actually written as
|
|
|
- # POINTER(c_void), so it can be treated as a real pointer.
|
|
|
- _fields_ = [("dummy", c_int)]
|
|
|
-
|
|
|
-
|
|
|
-def POINTER(obj):
|
|
|
- p = ctypes.POINTER(obj)
|
|
|
-
|
|
|
- # Convert None to a real NULL pointer to work around bugs
|
|
|
- # in how ctypes handles None on 64-bit platforms
|
|
|
- if not isinstance(p.from_param, classmethod):
|
|
|
-
|
|
|
- def from_param(cls, x):
|
|
|
- if x is None:
|
|
|
- return cls()
|
|
|
- else:
|
|
|
- return x
|
|
|
-
|
|
|
- p.from_param = classmethod(from_param)
|
|
|
-
|
|
|
- return p
|
|
|
-
|
|
|
-
|
|
|
-class UserString:
|
|
|
- def __init__(self, seq):
|
|
|
- if isinstance(seq, basestring):
|
|
|
- self.data = seq
|
|
|
- elif isinstance(seq, UserString):
|
|
|
- self.data = seq.data[:]
|
|
|
- else:
|
|
|
- self.data = str(seq)
|
|
|
-
|
|
|
- def __str__(self):
|
|
|
- return str(self.data)
|
|
|
-
|
|
|
- def __repr__(self):
|
|
|
- return repr(self.data)
|
|
|
-
|
|
|
- def __int__(self):
|
|
|
- return int(self.data)
|
|
|
-
|
|
|
- def __long__(self):
|
|
|
- return long(self.data)
|
|
|
-
|
|
|
- def __float__(self):
|
|
|
- return float(self.data)
|
|
|
-
|
|
|
- def __complex__(self):
|
|
|
- return complex(self.data)
|
|
|
-
|
|
|
- def __hash__(self):
|
|
|
- return hash(self.data)
|
|
|
-
|
|
|
- def __cmp__(self, string):
|
|
|
- if isinstance(string, UserString):
|
|
|
- return cmp(self.data, string.data)
|
|
|
- else:
|
|
|
- return cmp(self.data, string)
|
|
|
-
|
|
|
- def __contains__(self, char):
|
|
|
- return char in self.data
|
|
|
-
|
|
|
- def __len__(self):
|
|
|
- return len(self.data)
|
|
|
-
|
|
|
- def __getitem__(self, index):
|
|
|
- return self.__class__(self.data[index])
|
|
|
-
|
|
|
- def __getslice__(self, start, end):
|
|
|
- start = max(start, 0)
|
|
|
- end = max(end, 0)
|
|
|
- return self.__class__(self.data[start:end])
|
|
|
-
|
|
|
- def __add__(self, other):
|
|
|
- if isinstance(other, UserString):
|
|
|
- return self.__class__(self.data + other.data)
|
|
|
- elif isinstance(other, basestring):
|
|
|
- return self.__class__(self.data + other)
|
|
|
- else:
|
|
|
- return self.__class__(self.data + str(other))
|
|
|
-
|
|
|
- def __radd__(self, other):
|
|
|
- if isinstance(other, basestring):
|
|
|
- return self.__class__(other + self.data)
|
|
|
- else:
|
|
|
- return self.__class__(str(other) + self.data)
|
|
|
-
|
|
|
- def __mul__(self, n):
|
|
|
- return self.__class__(self.data * n)
|
|
|
-
|
|
|
- __rmul__ = __mul__
|
|
|
-
|
|
|
- def __mod__(self, args):
|
|
|
- return self.__class__(self.data % args)
|
|
|
-
|
|
|
- # the following methods are defined in alphabetical order:
|
|
|
- def capitalize(self):
|
|
|
- return self.__class__(self.data.capitalize())
|
|
|
-
|
|
|
- def center(self, width, *args):
|
|
|
- return self.__class__(self.data.center(width, *args))
|
|
|
-
|
|
|
- def count(self, sub, start=0, end=sys.maxint):
|
|
|
- return self.data.count(sub, start, end)
|
|
|
-
|
|
|
- def decode(self, encoding=None, errors=None): # XXX improve this?
|
|
|
- if encoding:
|
|
|
- if errors:
|
|
|
- return self.__class__(self.data.decode(encoding, errors))
|
|
|
- else:
|
|
|
- return self.__class__(self.data.decode(encoding))
|
|
|
- else:
|
|
|
- return self.__class__(self.data.decode())
|
|
|
-
|
|
|
- def encode(self, encoding=None, errors=None): # XXX improve this?
|
|
|
- if encoding:
|
|
|
- if errors:
|
|
|
- return self.__class__(self.data.encode(encoding, errors))
|
|
|
- else:
|
|
|
- return self.__class__(self.data.encode(encoding))
|
|
|
- else:
|
|
|
- return self.__class__(self.data.encode())
|
|
|
-
|
|
|
- def endswith(self, suffix, start=0, end=sys.maxint):
|
|
|
- return self.data.endswith(suffix, start, end)
|
|
|
-
|
|
|
- def expandtabs(self, tabsize=8):
|
|
|
- return self.__class__(self.data.expandtabs(tabsize))
|
|
|
-
|
|
|
- def find(self, sub, start=0, end=sys.maxint):
|
|
|
- return self.data.find(sub, start, end)
|
|
|
-
|
|
|
- def index(self, sub, start=0, end=sys.maxint):
|
|
|
- return self.data.index(sub, start, end)
|
|
|
-
|
|
|
- def isalpha(self):
|
|
|
- return self.data.isalpha()
|
|
|
-
|
|
|
- def isalnum(self):
|
|
|
- return self.data.isalnum()
|
|
|
-
|
|
|
- def isdecimal(self):
|
|
|
- return self.data.isdecimal()
|
|
|
-
|
|
|
- def isdigit(self):
|
|
|
- return self.data.isdigit()
|
|
|
-
|
|
|
- def islower(self):
|
|
|
- return self.data.islower()
|
|
|
-
|
|
|
- def isnumeric(self):
|
|
|
- return self.data.isnumeric()
|
|
|
-
|
|
|
- def isspace(self):
|
|
|
- return self.data.isspace()
|
|
|
-
|
|
|
- def istitle(self):
|
|
|
- return self.data.istitle()
|
|
|
-
|
|
|
- def isupper(self):
|
|
|
- return self.data.isupper()
|
|
|
-
|
|
|
- def join(self, seq):
|
|
|
- return self.data.join(seq)
|
|
|
-
|
|
|
- def ljust(self, width, *args):
|
|
|
- return self.__class__(self.data.ljust(width, *args))
|
|
|
-
|
|
|
- def lower(self):
|
|
|
- return self.__class__(self.data.lower())
|
|
|
-
|
|
|
- def lstrip(self, chars=None):
|
|
|
- return self.__class__(self.data.lstrip(chars))
|
|
|
-
|
|
|
- def partition(self, sep):
|
|
|
- return self.data.partition(sep)
|
|
|
-
|
|
|
- def replace(self, old, new, maxsplit=-1):
|
|
|
- return self.__class__(self.data.replace(old, new, maxsplit))
|
|
|
-
|
|
|
- def rfind(self, sub, start=0, end=sys.maxint):
|
|
|
- return self.data.rfind(sub, start, end)
|
|
|
-
|
|
|
- def rindex(self, sub, start=0, end=sys.maxint):
|
|
|
- return self.data.rindex(sub, start, end)
|
|
|
-
|
|
|
- def rjust(self, width, *args):
|
|
|
- return self.__class__(self.data.rjust(width, *args))
|
|
|
-
|
|
|
- def rpartition(self, sep):
|
|
|
- return self.data.rpartition(sep)
|
|
|
-
|
|
|
- def rstrip(self, chars=None):
|
|
|
- return self.__class__(self.data.rstrip(chars))
|
|
|
-
|
|
|
- def split(self, sep=None, maxsplit=-1):
|
|
|
- return self.data.split(sep, maxsplit)
|
|
|
-
|
|
|
- def rsplit(self, sep=None, maxsplit=-1):
|
|
|
- return self.data.rsplit(sep, maxsplit)
|
|
|
-
|
|
|
- def splitlines(self, keepends=0):
|
|
|
- return self.data.splitlines(keepends)
|
|
|
-
|
|
|
- def startswith(self, prefix, start=0, end=sys.maxint):
|
|
|
- return self.data.startswith(prefix, start, end)
|
|
|
-
|
|
|
- def strip(self, chars=None):
|
|
|
- return self.__class__(self.data.strip(chars))
|
|
|
-
|
|
|
- def swapcase(self):
|
|
|
- return self.__class__(self.data.swapcase())
|
|
|
-
|
|
|
- def title(self):
|
|
|
- return self.__class__(self.data.title())
|
|
|
-
|
|
|
- def translate(self, *args):
|
|
|
- return self.__class__(self.data.translate(*args))
|
|
|
-
|
|
|
- def upper(self):
|
|
|
- return self.__class__(self.data.upper())
|
|
|
-
|
|
|
- def zfill(self, width):
|
|
|
- return self.__class__(self.data.zfill(width))
|
|
|
-
|
|
|
-
|
|
|
-class MutableString(UserString):
|
|
|
- """mutable string objects
|
|
|
-
|
|
|
- Python strings are immutable objects. This has the advantage, that
|
|
|
- strings may be used as dictionary keys. If this property isn't needed
|
|
|
- and you insist on changing string values in place instead, you may cheat
|
|
|
- and use MutableString.
|
|
|
-
|
|
|
- But the purpose of this class is an educational one: to prevent
|
|
|
- people from inventing their own mutable string class derived
|
|
|
- from UserString and than forget thereby to remove (override) the
|
|
|
- __hash__ method inherited from UserString. This would lead to
|
|
|
- errors that would be very hard to track down.
|
|
|
-
|
|
|
- A faster and better solution is to rewrite your program using lists."""
|
|
|
-
|
|
|
- def __init__(self, string=""):
|
|
|
- self.data = string
|
|
|
-
|
|
|
- def __hash__(self):
|
|
|
- raise TypeError("unhashable type (it is mutable)")
|
|
|
-
|
|
|
- def __setitem__(self, index, sub):
|
|
|
- if index < 0:
|
|
|
- index += len(self.data)
|
|
|
- if index < 0 or index >= len(self.data):
|
|
|
- raise IndexError
|
|
|
- self.data = self.data[:index] + sub + self.data[index + 1 :]
|
|
|
-
|
|
|
- def __delitem__(self, index):
|
|
|
- if index < 0:
|
|
|
- index += len(self.data)
|
|
|
- if index < 0 or index >= len(self.data):
|
|
|
- raise IndexError
|
|
|
- self.data = self.data[:index] + self.data[index + 1 :]
|
|
|
-
|
|
|
- def __setslice__(self, start, end, sub):
|
|
|
- start = max(start, 0)
|
|
|
- end = max(end, 0)
|
|
|
- if isinstance(sub, UserString):
|
|
|
- self.data = self.data[:start] + sub.data + self.data[end:]
|
|
|
- elif isinstance(sub, basestring):
|
|
|
- self.data = self.data[:start] + sub + self.data[end:]
|
|
|
- else:
|
|
|
- self.data = self.data[:start] + str(sub) + self.data[end:]
|
|
|
-
|
|
|
- def __delslice__(self, start, end):
|
|
|
- start = max(start, 0)
|
|
|
- end = max(end, 0)
|
|
|
- self.data = self.data[:start] + self.data[end:]
|
|
|
-
|
|
|
- def immutable(self):
|
|
|
- return UserString(self.data)
|
|
|
-
|
|
|
- def __iadd__(self, other):
|
|
|
- if isinstance(other, UserString):
|
|
|
- self.data += other.data
|
|
|
- elif isinstance(other, basestring):
|
|
|
- self.data += other
|
|
|
- else:
|
|
|
- self.data += str(other)
|
|
|
- return self
|
|
|
-
|
|
|
- def __imul__(self, n):
|
|
|
- self.data *= n
|
|
|
- return self
|
|
|
-
|
|
|
-
|
|
|
-class String(MutableString, Union):
|
|
|
-
|
|
|
- _fields_ = [("raw", POINTER(c_char)), ("data", c_char_p)]
|
|
|
-
|
|
|
- def __init__(self, obj=""):
|
|
|
- if isinstance(obj, (str, unicode, UserString)):
|
|
|
- self.data = str(obj)
|
|
|
- else:
|
|
|
- self.raw = obj
|
|
|
-
|
|
|
- def __len__(self):
|
|
|
- return self.data and len(self.data) or 0
|
|
|
-
|
|
|
- def from_param(cls, obj):
|
|
|
- # Convert None or 0
|
|
|
- if obj is None or obj == 0:
|
|
|
- return cls(POINTER(c_char)())
|
|
|
-
|
|
|
- # Convert from String
|
|
|
- elif isinstance(obj, String):
|
|
|
- return obj
|
|
|
-
|
|
|
- # Convert from str
|
|
|
- elif isinstance(obj, str):
|
|
|
- return cls(obj)
|
|
|
-
|
|
|
- # Convert from c_char_p
|
|
|
- elif isinstance(obj, c_char_p):
|
|
|
- return obj
|
|
|
-
|
|
|
- # Convert from POINTER(c_char)
|
|
|
- elif isinstance(obj, POINTER(c_char)):
|
|
|
- return obj
|
|
|
-
|
|
|
- # Convert from raw pointer
|
|
|
- elif isinstance(obj, int):
|
|
|
- return cls(cast(obj, POINTER(c_char)))
|
|
|
-
|
|
|
- # Convert from object
|
|
|
- else:
|
|
|
- return String.from_param(obj._as_parameter_)
|
|
|
-
|
|
|
- from_param = classmethod(from_param)
|
|
|
-
|
|
|
-
|
|
|
-def ReturnString(obj, func=None, arguments=None):
|
|
|
- return String.from_param(obj)
|
|
|
-
|
|
|
-
|
|
|
-# As of ctypes 1.0, ctypes does not support custom error-checking
|
|
|
-# functions on callbacks, nor does it support custom datatypes on
|
|
|
-# callbacks, so we must ensure that all callbacks return
|
|
|
-# primitive datatypes.
|
|
|
-#
|
|
|
-# Non-primitive return values wrapped with UNCHECKED won't be
|
|
|
-# typechecked, and will be converted to c_void_p.
|
|
|
-def UNCHECKED(type):
|
|
|
- if hasattr(type, "_type_") and isinstance(type._type_, str) and type._type_ != "P":
|
|
|
- return type
|
|
|
- else:
|
|
|
- return c_void_p
|
|
|
-
|
|
|
-
|
|
|
-# ctypes doesn't have direct support for variadic functions, so we have to write
|
|
|
-# our own wrapper class
|
|
|
-class _variadic_function(object):
|
|
|
- def __init__(self, func, restype, argtypes):
|
|
|
- self.func = func
|
|
|
- self.func.restype = restype
|
|
|
- self.argtypes = argtypes
|
|
|
-
|
|
|
- def _as_parameter_(self):
|
|
|
- # So we can pass this variadic function as a function pointer
|
|
|
- return self.func
|
|
|
-
|
|
|
- def __call__(self, *args):
|
|
|
- fixed_args = []
|
|
|
- i = 0
|
|
|
- for argtype in self.argtypes:
|
|
|
- # Typecheck what we can
|
|
|
- fixed_args.append(argtype.from_param(args[i]))
|
|
|
- i += 1
|
|
|
- return self.func(*fixed_args + list(args[i:]))
|
|
|
-
|
|
|
-
|
|
|
-def ord_if_char(value):
|
|
|
- """
|
|
|
- Simple helper used for casts to simple builtin types: if the argument is a
|
|
|
- string type, it will be converted to it's ordinal value.
|
|
|
-
|
|
|
- This function will raise an exception if the argument is string with more
|
|
|
- than one characters.
|
|
|
- """
|
|
|
- return ord(value) if isinstance(value, str) else value
|