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/codec010.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/codec010.py')
-rw-r--r-- | qpid/python/qpid/codec010.py | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/qpid/python/qpid/codec010.py b/qpid/python/qpid/codec010.py new file mode 100644 index 0000000000..94a1cd4263 --- /dev/null +++ b/qpid/python/qpid/codec010.py @@ -0,0 +1,401 @@ +# +# 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 datetime, string +from packer import Packer +from datatypes import serial, timestamp, RangedSet, Struct, UUID +from ops import Compound, PRIMITIVE, COMPOUND + +class CodecException(Exception): pass + +def direct(t): + return lambda x: t + +def map_str(s): + for c in s: + if ord(c) >= 0x80: + return "vbin16" + return "str16" + +class Codec(Packer): + + ENCODINGS = { + bool: direct("boolean"), + unicode: direct("str16"), + str: map_str, + buffer: direct("vbin32"), + int: direct("int64"), + long: direct("int64"), + float: direct("double"), + None.__class__: direct("void"), + list: direct("list"), + tuple: direct("list"), + dict: direct("map"), + timestamp: direct("datetime"), + datetime.datetime: direct("datetime"), + UUID: direct("uuid"), + Compound: direct("struct32") + } + + def encoding(self, obj): + enc = self._encoding(obj.__class__, obj) + if enc is None: + raise CodecException("no encoding for %r" % obj) + return PRIMITIVE[enc] + + def _encoding(self, klass, obj): + if self.ENCODINGS.has_key(klass): + return self.ENCODINGS[klass](obj) + for base in klass.__bases__: + result = self._encoding(base, obj) + if result != None: + return result + + def read_primitive(self, type): + return getattr(self, "read_%s" % type.NAME)() + def write_primitive(self, type, v): + getattr(self, "write_%s" % type.NAME)(v) + + def read_void(self): + return None + def write_void(self, v): + assert v == None + + def read_bit(self): + return True + def write_bit(self, b): + if not b: raise ValueError(b) + + def read_uint8(self): + return self.unpack("!B") + def write_uint8(self, n): + if n < 0 or n > 255: + raise CodecException("Cannot encode %d as uint8" % n) + return self.pack("!B", n) + + def read_int8(self): + return self.unpack("!b") + def write_int8(self, n): + if n < -128 or n > 127: + raise CodecException("Cannot encode %d as int8" % n) + self.pack("!b", n) + + def read_char(self): + return self.unpack("!c") + def write_char(self, c): + self.pack("!c", c) + + def read_boolean(self): + return self.read_uint8() != 0 + def write_boolean(self, b): + if b: n = 1 + else: n = 0 + self.write_uint8(n) + + + def read_uint16(self): + return self.unpack("!H") + def write_uint16(self, n): + if n < 0 or n > 65535: + raise CodecException("Cannot encode %d as uint16" % n) + self.pack("!H", n) + + def read_int16(self): + return self.unpack("!h") + def write_int16(self, n): + if n < -32768 or n > 32767: + raise CodecException("Cannot encode %d as int16" % n) + self.pack("!h", n) + + + def read_uint32(self): + return self.unpack("!L") + def write_uint32(self, n): + if n < 0 or n > 4294967295: + raise CodecException("Cannot encode %d as uint32" % n) + self.pack("!L", n) + + def read_int32(self): + return self.unpack("!l") + def write_int32(self, n): + if n < -2147483648 or n > 2147483647: + raise CodecException("Cannot encode %d as int32" % n) + self.pack("!l", n) + + def read_float(self): + return self.unpack("!f") + def write_float(self, f): + self.pack("!f", f) + + def read_sequence_no(self): + return serial(self.read_uint32()) + def write_sequence_no(self, n): + self.write_uint32(n.value) + + + def read_uint64(self): + return self.unpack("!Q") + def write_uint64(self, n): + self.pack("!Q", n) + + def read_int64(self): + return self.unpack("!q") + def write_int64(self, n): + self.pack("!q", n) + + def read_datetime(self): + return timestamp(self.read_uint64()) + def write_datetime(self, t): + if isinstance(t, datetime.datetime): + t = timestamp(t) + self.write_uint64(t) + + def read_double(self): + return self.unpack("!d") + def write_double(self, d): + self.pack("!d", d) + + def read_vbin8(self): + return self.read(self.read_uint8()) + def write_vbin8(self, b): + if isinstance(b, buffer): + b = str(b) + self.write_uint8(len(b)) + self.write(b) + + def read_str8(self): + return self.read_vbin8().decode("utf8") + def write_str8(self, s): + self.write_vbin8(s.encode("utf8")) + + def read_str16(self): + return self.read_vbin16().decode("utf8") + def write_str16(self, s): + self.write_vbin16(s.encode("utf8")) + + def read_str16_latin(self): + return self.read_vbin16().decode("iso-8859-15") + def write_str16_latin(self, s): + self.write_vbin16(s.encode("iso-8859-15")) + + + def read_vbin16(self): + return self.read(self.read_uint16()) + def write_vbin16(self, b): + if isinstance(b, buffer): + b = str(b) + self.write_uint16(len(b)) + self.write(b) + + def read_sequence_set(self): + result = RangedSet() + size = self.read_uint16() + nranges = size/8 + while nranges > 0: + lower = self.read_sequence_no() + upper = self.read_sequence_no() + result.add(lower, upper) + nranges -= 1 + return result + def write_sequence_set(self, ss): + size = 8*len(ss.ranges) + self.write_uint16(size) + for range in ss.ranges: + self.write_sequence_no(range.lower) + self.write_sequence_no(range.upper) + + def read_vbin32(self): + return self.read(self.read_uint32()) + def write_vbin32(self, b): + if isinstance(b, buffer): + b = str(b) + self.write_uint32(len(b)) + self.write(b) + + def read_map(self): + sc = StringCodec(self.read_vbin32()) + if not sc.encoded: + return None + count = sc.read_uint32() + result = {} + while sc.encoded: + k = sc.read_str8() + code = sc.read_uint8() + type = PRIMITIVE[code] + v = sc.read_primitive(type) + result[k] = v + return result + + def _write_map_elem(self, k, v): + type = self.encoding(v) + sc = StringCodec() + sc.write_str8(k) + sc.write_uint8(type.CODE) + sc.write_primitive(type, v) + return sc.encoded + + def write_map(self, m): + sc = StringCodec() + if m is not None: + sc.write_uint32(len(m)) + sc.write(string.joinfields(map(self._write_map_elem, m.keys(), m.values()), "")) + self.write_vbin32(sc.encoded) + + def read_array(self): + sc = StringCodec(self.read_vbin32()) + if not sc.encoded: + return None + type = PRIMITIVE[sc.read_uint8()] + count = sc.read_uint32() + result = [] + while count > 0: + result.append(sc.read_primitive(type)) + count -= 1 + return result + def write_array(self, a): + sc = StringCodec() + if a is not None: + if len(a) > 0: + type = self.encoding(a[0]) + else: + type = self.encoding(None) + sc.write_uint8(type.CODE) + sc.write_uint32(len(a)) + for o in a: + sc.write_primitive(type, o) + self.write_vbin32(sc.encoded) + + def read_list(self): + sc = StringCodec(self.read_vbin32()) + if not sc.encoded: + return None + count = sc.read_uint32() + result = [] + while count > 0: + type = PRIMITIVE[sc.read_uint8()] + result.append(sc.read_primitive(type)) + count -= 1 + return result + def write_list(self, l): + sc = StringCodec() + if l is not None: + sc.write_uint32(len(l)) + for o in l: + type = self.encoding(o) + sc.write_uint8(type.CODE) + sc.write_primitive(type, o) + self.write_vbin32(sc.encoded) + + def read_struct32(self): + size = self.read_uint32() + code = self.read_uint16() + cls = COMPOUND[code] + op = cls() + self.read_fields(op) + return op + def write_struct32(self, value): + self.write_compound(value) + + def read_compound(self, cls): + size = self.read_size(cls.SIZE) + if cls.CODE is not None: + code = self.read_uint16() + assert code == cls.CODE + op = cls() + self.read_fields(op) + return op + def write_compound(self, op): + sc = StringCodec() + if op.CODE is not None: + sc.write_uint16(op.CODE) + sc.write_fields(op) + self.write_size(op.SIZE, len(sc.encoded)) + self.write(sc.encoded) + + def read_fields(self, op): + flags = 0 + for i in range(op.PACK): + flags |= (self.read_uint8() << 8*i) + + for i in range(len(op.FIELDS)): + f = op.FIELDS[i] + if flags & (0x1 << i): + if COMPOUND.has_key(f.type): + value = self.read_compound(COMPOUND[f.type]) + else: + value = getattr(self, "read_%s" % f.type)() + setattr(op, f.name, value) + def write_fields(self, op): + flags = 0 + for i in range(len(op.FIELDS)): + f = op.FIELDS[i] + value = getattr(op, f.name) + if f.type == "bit": + present = value + else: + present = value != None + if present: + flags |= (0x1 << i) + for i in range(op.PACK): + self.write_uint8((flags >> 8*i) & 0xFF) + for i in range(len(op.FIELDS)): + f = op.FIELDS[i] + if flags & (0x1 << i): + if COMPOUND.has_key(f.type): + enc = self.write_compound + else: + enc = getattr(self, "write_%s" % f.type) + value = getattr(op, f.name) + enc(value) + + def read_size(self, width): + if width > 0: + attr = "read_uint%d" % (width*8) + return getattr(self, attr)() + def write_size(self, width, n): + if width > 0: + attr = "write_uint%d" % (width*8) + getattr(self, attr)(n) + + def read_uuid(self): + return UUID(bytes=self.unpack("16s")) + def write_uuid(self, s): + if isinstance(s, UUID): + s = s.bytes + self.pack("16s", s) + + def read_bin128(self): + return self.unpack("16s") + def write_bin128(self, b): + self.pack("16s", b) + + + +class StringCodec(Codec): + + def __init__(self, encoded = ""): + self.encoded = encoded + + def read(self, n): + result = self.encoded[:n] + self.encoded = self.encoded[n:] + return result + + def write(self, s): + self.encoded += s |