diff options
| author | Rafael H. Schloming <rhs@apache.org> | 2007-08-22 13:39:04 +0000 |
|---|---|---|
| committer | Rafael H. Schloming <rhs@apache.org> | 2007-08-22 13:39:04 +0000 |
| commit | 51c4f612aec73b473477cacb786865c76284e002 (patch) | |
| tree | 64ab65d87efae9f81ca6e342693cb44f53e458c5 /python | |
| parent | caa402b97879d849273604842c1ec6bb63e40f26 (diff) | |
| download | qpid-python-51c4f612aec73b473477cacb786865c76284e002.tar.gz | |
added support for 0-10 style header encoding
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@568607 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'python')
| -rwxr-xr-x | python/hello-world | 5 | ||||
| -rw-r--r-- | python/qpid/__init__.py | 19 | ||||
| -rw-r--r-- | python/qpid/codec.py | 36 | ||||
| -rw-r--r-- | python/qpid/connection.py | 58 | ||||
| -rw-r--r-- | python/qpid/spec.py | 5 | ||||
| -rw-r--r-- | python/qpid/testlib.py | 5 |
6 files changed, 110 insertions, 18 deletions
diff --git a/python/hello-world b/python/hello-world index 4fb065ae53..b3170c8e0c 100755 --- a/python/hello-world +++ b/python/hello-world @@ -11,5 +11,6 @@ ch.queue_declare(queue="test") ch.queue_bind(exchange="amq.direct", queue="test", routing_key="test") print ch.queue_query(queue="test") ch.message_subscribe(queue="test", destination="test") -ch.message_transfer(destination="amq.direct", - content=Content("hello world")) +msg = Content("hello world") +msg["content_type"] = "text/plain" +ch.message_transfer(destination="amq.direct", content=msg) diff --git a/python/qpid/__init__.py b/python/qpid/__init__.py index 4aeccae38e..3f6d82b89e 100644 --- a/python/qpid/__init__.py +++ b/python/qpid/__init__.py @@ -31,13 +31,28 @@ class Struct: raise AttributeError(attr) return field - def __setattr__(self, attr, value): + def has(self, name): + return self.type.fields.byname.has_key(name) + + def set(self, attr, value): self._check(attr) self._values[attr] = value - def __getattr__(self, attr): + def get(self, attr): field = self._check(attr) return self._values.get(attr, field.default()) + def __setattr__(self, attr, value): + self.set(attr, value) + + def __getattr__(self, attr): + return self.get(attr) + + def __setitem__(self, attr, value): + self.set(attr, value) + + def __getitem__(self, attr): + return self.get(attr) + def __str__(self): return "%s %s" % (self.type.type, self._values) diff --git a/python/qpid/codec.py b/python/qpid/codec.py index 3920f2c8d9..ae113619ae 100644 --- a/python/qpid/codec.py +++ b/python/qpid/codec.py @@ -26,7 +26,7 @@ fields. The unit test for this module is located in tests/codec.py """ -import re, qpid +import re, qpid, spec from cStringIO import StringIO from struct import * from reference import ReferenceId @@ -113,13 +113,19 @@ class Codec: """ calls the appropriate encode function e.g. encode_octet, encode_short etc. """ - getattr(self, "encode_" + type)(value) + if isinstance(type, spec.Struct): + self.encode_struct(type, value) + else: + getattr(self, "encode_" + type)(value) def decode(self, type): """ calls the appropriate decode function e.g. decode_octet, decode_short etc. """ - return getattr(self, "decode_" + type)() + if isinstance(type, spec.Struct): + return self.decode_struct(type) + else: + return getattr(self, "decode_" + type)() def encode_bit(self, o): """ @@ -358,20 +364,30 @@ class Codec: def decode_uuid(self): return self.decode_longstr() + def encode_struct(self, type, s): + for f in type.fields: + if s == None: + val = f.default() + else: + val = s.get(f.name) + self.encode(f.type, val) + self.flush() + + def decode_struct(self, type): + s = qpid.Struct(type) + for f in type.fields: + s.set(f.name, self.decode(f.type)) + return s + def encode_long_struct(self, s): enc = StringIO() codec = Codec(enc, self.spec) type = s.type codec.encode_short(type.type) - for f in type.fields: - codec.encode(f.type, getattr(s, f.name)) - codec.flush() + codec.encode_struct(type, s) self.encode_longstr(enc.getvalue()) def decode_long_struct(self): codec = Codec(StringIO(self.decode_longstr()), self.spec) type = self.spec.structs[codec.decode_short()] - s = qpid.Struct(type) - for f in type.fields: - setattr(s, f.name, codec.decode(f.type)) - return s + return codec.decode_struct(type) diff --git a/python/qpid/connection.py b/python/qpid/connection.py index 58235117ef..46b58e83b7 100644 --- a/python/qpid/connection.py +++ b/python/qpid/connection.py @@ -23,7 +23,7 @@ to read and write Frame objects. This could be used by a client, server, or even a proxy implementation. """ -import socket, codec,logging +import socket, codec, logging, qpid from cStringIO import StringIO from spec import load from codec import EOF @@ -238,6 +238,11 @@ class Response(Frame): def __str__(self): return "[%s] Response(%s,%s,%s) %s" % (self.channel, self.id, self.request_id, self.batch_offset, self.method) +def uses_struct_encoding(spec): + return (spec.major == 0 and + spec.minor == 10 and + "transitional" not in spec.file) + class Header(Frame): type = "frame_header" @@ -258,6 +263,33 @@ class Header(Frame): del self.properties[name] def encode(self, c): + if uses_struct_encoding(c.spec): + self.encode_structs(c) + else: + self.encode_legacy(c) + + def encode_structs(self, c): + # XXX + structs = [qpid.Struct(c.spec.domains.byname["delivery_properties"].type), + qpid.Struct(c.spec.domains.byname["message_properties"].type)] + + # XXX + props = self.properties.copy() + for k in self.properties: + for s in structs: + if s.has(k): + s.set(k, props.pop(k)) + if props: + raise TypeError("no such property: %s" % (", ".join(props))) + + # message properties store the content-length now, and weight is + # deprecated + structs[1].content_length = self.size + + for s in structs: + c.encode_long_struct(s) + + def encode_legacy(self, c): c.encode_short(self.klass.id) c.encode_short(self.weight) c.encode_longlong(self.size) @@ -287,6 +319,30 @@ class Header(Frame): c.encode(f.type, v) def decode(spec, c, size): + if uses_struct_encoding(spec): + return Header.decode_structs(spec, c, size) + else: + return Header.decode_legacy(spec, c, size) + + @staticmethod + def decode_structs(spec, c, size): + structs = [] + start = c.nread + while c.nread - start < size: + structs.append(c.decode_long_struct()) + + # XXX + props = {} + length = None + for s in structs: + for f in s.type.fields: + props[f.name] = s.get(f.name) + if f.name == "content_length": + length = s.get(f.name) + return Header(None, 0, length, props) + + @staticmethod + def decode_legacy(spec, c, size): klass = spec.classes.byid[c.decode_short()] weight = c.decode_short() size = c.decode_longlong() diff --git a/python/qpid/spec.py b/python/qpid/spec.py index 8a511bcb3d..3febab7e09 100644 --- a/python/qpid/spec.py +++ b/python/qpid/spec.py @@ -298,7 +298,10 @@ class Field(Metadata): self.docs = docs def default(self): - return Method.DEFAULTS[self.type] + if isinstance(self.type, Struct): + return None + else: + return Method.DEFAULTS[self.type] def get_result(nd, spec): result = nd["result"] diff --git a/python/qpid/testlib.py b/python/qpid/testlib.py index c06a252f16..0b2a1b78d6 100644 --- a/python/qpid/testlib.py +++ b/python/qpid/testlib.py @@ -21,7 +21,7 @@ # Support library for qpid python tests. # -import sys, re, unittest, os, random, logging +import sys, re, unittest, os, random, logging, traceback import qpid.client, qpid.spec import Queue from fnmatch import fnmatch @@ -217,7 +217,8 @@ class TestBase(unittest.TestCase): for ch, ex in self.exchanges: ch.exchange_delete(exchange=ex) except: - print "Error on tearDown:", sys.exc_info() + print "Error on tearDown:" + print traceback.print_exc() if not self.client.closed: self.client.channel(0).connection_close(reply_code=200) |
