summaryrefslogtreecommitdiff
path: root/qpid/python/qpid/datatypes.py
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/python/qpid/datatypes.py')
-rw-r--r--qpid/python/qpid/datatypes.py385
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)