diff options
author | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
---|---|---|
committer | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
commit | 66765100f4257159622cefe57bed50125a5ad017 (patch) | |
tree | a88ee23bb194eb91f0ebb2d9b23ff423e3ea8e37 /qpid/python/qpid/datatypes.py | |
parent | 1aeaa7b16e5ce54f10c901d75c4d40f9f88b9db6 (diff) | |
parent | 88b98b2f4152ef59a671fad55a0d08338b6b78ca (diff) | |
download | qpid-python-66765100f4257159622cefe57bed50125a5ad017.tar.gz |
Creating a branch for experimenting with some ideas for JMS client.rajith_jms_client
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/rajith_jms_client@1128369 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/python/qpid/datatypes.py')
-rw-r--r-- | qpid/python/qpid/datatypes.py | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/qpid/python/qpid/datatypes.py b/qpid/python/qpid/datatypes.py new file mode 100644 index 0000000000..ca1466c261 --- /dev/null +++ b/qpid/python/qpid/datatypes.py @@ -0,0 +1,385 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import threading, struct, datetime, time +from exceptions import Timeout + +class Struct: + + def __init__(self, _type, *args, **kwargs): + if len(args) > len(_type.fields): + raise TypeError("%s() takes at most %s arguments (%s given)" % + (_type.name, len(_type.fields), len(args))) + + self._type = _type + + idx = 0 + for field in _type.fields: + if idx < len(args): + arg = args[idx] + if kwargs.has_key(field.name): + raise TypeError("%s() got multiple values for keyword argument '%s'" % + (_type.name, field.name)) + elif kwargs.has_key(field.name): + arg = kwargs.pop(field.name) + else: + arg = field.default() + setattr(self, field.name, arg) + idx += 1 + + if kwargs: + unexpected = kwargs.keys()[0] + raise TypeError("%s() got an unexpected keyword argument '%s'" % + (_type.name, unexpected)) + + def __getitem__(self, name): + return getattr(self, name) + + def __setitem__(self, name, value): + if not hasattr(self, name): + raise AttributeError("'%s' object has no attribute '%s'" % + (self._type.name, name)) + setattr(self, name, value) + + def __repr__(self): + fields = [] + for f in self._type.fields: + v = self[f.name] + if f.type.is_present(v): + fields.append("%s=%r" % (f.name, v)) + return "%s(%s)" % (self._type.name, ", ".join(fields)) + +class Message: + + def __init__(self, *args): + if args: + self.body = args[-1] + else: + self.body = None + if len(args) > 1: + self.headers = list(args[:-1]) + else: + self.headers = None + self.id = None + + def has(self, name): + return self.get(name) != None + + def get(self, name): + if self.headers: + for h in self.headers: + if h.NAME == name: + return h + return None + + def set(self, header): + if self.headers is None: + self.headers = [] + idx = 0 + while idx < len(self.headers): + if self.headers[idx].NAME == header.NAME: + self.headers[idx] = header + return + idx += 1 + self.headers.append(header) + + def clear(self, name): + idx = 0 + while idx < len(self.headers): + if self.headers[idx].NAME == name: + del self.headers[idx] + return + idx += 1 + + def __repr__(self): + args = [] + if self.headers: + args.extend(map(repr, self.headers)) + if self.body: + args.append(repr(self.body)) + if self.id is not None: + args.append("id=%s" % self.id) + return "Message(%s)" % ", ".join(args) + +def serial(o): + if isinstance(o, Serial): + return o + else: + return Serial(o) + +class Serial: + + def __init__(self, value): + self.value = value & 0xFFFFFFFFL + + def __hash__(self): + return hash(self.value) + + def __cmp__(self, other): + if other.__class__ not in (int, long, Serial): + return 1 + + other = serial(other) + + delta = (self.value - other.value) & 0xFFFFFFFFL + neg = delta & 0x80000000L + mag = delta & 0x7FFFFFFF + + if neg: + return -mag + else: + return mag + + def __add__(self, other): + return Serial(self.value + other) + + def __sub__(self, other): + if isinstance(other, Serial): + return self.value - other.value + else: + return Serial(self.value - other) + + def __repr__(self): + return "serial(%s)" % self.value + + def __str__(self): + return str(self.value) + +class Range: + + def __init__(self, lower, upper = None): + self.lower = serial(lower) + if upper is None: + self.upper = self.lower + else: + self.upper = serial(upper) + + def __contains__(self, n): + return self.lower <= n and n <= self.upper + + def __iter__(self): + i = self.lower + while i <= self.upper: + yield i + i += 1 + + def touches(self, r): + # XXX: are we doing more checks than we need? + return (self.lower - 1 in r or + self.upper + 1 in r or + r.lower - 1 in self or + r.upper + 1 in self or + self.lower in r or + self.upper in r or + r.lower in self or + r.upper in self) + + def span(self, r): + return Range(min(self.lower, r.lower), max(self.upper, r.upper)) + + def intersect(self, r): + lower = max(self.lower, r.lower) + upper = min(self.upper, r.upper) + if lower > upper: + return None + else: + return Range(lower, upper) + + def __repr__(self): + return "%s-%s" % (self.lower, self.upper) + +class RangedSet: + + def __init__(self, *args): + self.ranges = [] + for n in args: + self.add(n) + + def __contains__(self, n): + for r in self.ranges: + if n in r: + return True + return False + + def add_range(self, range): + idx = 0 + while idx < len(self.ranges): + r = self.ranges[idx] + if range.touches(r): + del self.ranges[idx] + range = range.span(r) + elif range.upper < r.lower: + self.ranges.insert(idx, range) + return + else: + idx += 1 + self.ranges.append(range) + + def add(self, lower, upper = None): + self.add_range(Range(lower, upper)) + + def empty(self): + for r in self.ranges: + if r.lower <= r.upper: + return False + return True + + def max(self): + if self.ranges: + return self.ranges[-1].upper + else: + return None + + def min(self): + if self.ranges: + return self.ranges[0].lower + else: + return None + + def __iter__(self): + return iter(self.ranges) + + def __repr__(self): + return str(self.ranges) + +class Future: + def __init__(self, initial=None, exception=Exception): + self.value = initial + self._error = None + self._set = threading.Event() + self.exception = exception + + def error(self, error): + self._error = error + self._set.set() + + def set(self, value): + self.value = value + self._set.set() + + def get(self, timeout=None): + self._set.wait(timeout) + if self._set.isSet(): + if self._error != None: + raise self.exception(self._error) + return self.value + else: + raise Timeout() + + def is_set(self): + return self._set.isSet() + +try: + from uuid import uuid4 + from uuid import UUID +except ImportError: + class UUID: + def __init__(self, hex=None, bytes=None): + if [hex, bytes].count(None) != 1: + raise TypeErrror("need one of hex or bytes") + if bytes is not None: + self.bytes = bytes + elif hex is not None: + fields=hex.split("-") + fields[4:5] = [fields[4][:4], fields[4][4:]] + self.bytes = struct.pack("!LHHHHL", *[int(x,16) for x in fields]) + + def __cmp__(self, other): + if isinstance(other, UUID): + return cmp(self.bytes, other.bytes) + else: + return -1 + + def __str__(self): + return "%08x-%04x-%04x-%04x-%04x%08x" % struct.unpack("!LHHHHL", self.bytes) + + def __repr__(self): + return "UUID(%r)" % str(self) + + def __hash__(self): + return self.bytes.__hash__() + + import os, random, socket, time + rand = random.Random() + rand.seed((os.getpid(), time.time(), socket.gethostname())) + def random_uuid(): + bytes = [rand.randint(0, 255) for i in xrange(16)] + + # From RFC4122, the version bits are set to 0100 + bytes[7] &= 0x0F + bytes[7] |= 0x40 + + # From RFC4122, the top two bits of byte 8 get set to 01 + bytes[8] &= 0x3F + bytes[8] |= 0x80 + return "".join(map(chr, bytes)) + + def uuid4(): + return UUID(bytes=random_uuid()) + +def parseUUID(str): + return UUID(hex=str) + +class timestamp(float): + + def __new__(cls, obj=None): + if obj is None: + obj = time.time() + elif isinstance(obj, datetime.datetime): + obj = time.mktime(obj.timetuple()) + 1e-6 * obj.microsecond + return super(timestamp, cls).__new__(cls, obj) + + def datetime(self): + return datetime.datetime.fromtimestamp(self) + + def __add__(self, other): + if isinstance(other, datetime.timedelta): + return timestamp(self.datetime() + other) + else: + return timestamp(float(self) + other) + + def __sub__(self, other): + if isinstance(other, datetime.timedelta): + return timestamp(self.datetime() - other) + else: + return timestamp(float(self) - other) + + def __radd__(self, other): + if isinstance(other, datetime.timedelta): + return timestamp(self.datetime() + other) + else: + return timestamp(other + float(self)) + + def __rsub__(self, other): + if isinstance(other, datetime.timedelta): + return timestamp(self.datetime() - other) + else: + return timestamp(other - float(self)) + + def __neg__(self): + return timestamp(-float(self)) + + def __pos__(self): + return self + + def __abs__(self): + return timestamp(abs(float(self))) + + def __repr__(self): + return "timestamp(%r)" % float(self) |