summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorRafael H. Schloming <rhs@apache.org>2007-08-22 13:39:04 +0000
committerRafael H. Schloming <rhs@apache.org>2007-08-22 13:39:04 +0000
commit51c4f612aec73b473477cacb786865c76284e002 (patch)
tree64ab65d87efae9f81ca6e342693cb44f53e458c5 /python
parentcaa402b97879d849273604842c1ec6bb63e40f26 (diff)
downloadqpid-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-xpython/hello-world5
-rw-r--r--python/qpid/__init__.py19
-rw-r--r--python/qpid/codec.py36
-rw-r--r--python/qpid/connection.py58
-rw-r--r--python/qpid/spec.py5
-rw-r--r--python/qpid/testlib.py5
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)