You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rh...@apache.org on 2007/09/27 20:56:24 UTC
svn commit: r580122 - in /incubator/qpid/trunk/qpid/python: qpid/codec.py
qpid/spec.py tests/codec.py
Author: rhs
Date: Thu Sep 27 11:56:23 2007
New Revision: 580122
URL: http://svn.apache.org/viewvc?rev=580122&view=rev
Log:
added support for 0-10 field table encoding
Modified:
incubator/qpid/trunk/qpid/python/qpid/codec.py
incubator/qpid/trunk/qpid/python/qpid/spec.py
incubator/qpid/trunk/qpid/python/tests/codec.py
Modified: incubator/qpid/trunk/qpid/python/qpid/codec.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/codec.py?rev=580122&r1=580121&r2=580122&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/codec.py (original)
+++ incubator/qpid/trunk/qpid/python/qpid/codec.py Thu Sep 27 11:56:23 2007
@@ -34,6 +34,11 @@
class EOF(Exception):
pass
+TYPE_ALIASES = {
+ "long_string": "longstr",
+ "unsigned_int": "long"
+ }
+
class Codec:
"""
@@ -51,6 +56,40 @@
self.incoming_bits = []
self.outgoing_bits = []
+ self.types = {}
+ self.codes = {}
+ self.encodings = {
+ basestring: "longstr",
+ int: "long",
+ long: "long",
+ None.__class__:"void",
+ list: "sequence",
+ tuple: "sequence",
+ dict: "table"
+ }
+
+ if False:
+ for constant in self.spec.constants:
+ if constant.klass == "field-table-type":
+ type = constant.name.replace("field_table_", "")
+ self.typecode(constant.id, TYPE_ALIASES.get(type, type))
+
+ if not self.types:
+ self.typecode(ord('S'), "longstr")
+ self.typecode(ord('I'), "long")
+
+ def typecode(self, code, type):
+ self.types[code] = type
+ self.codes[type] = code
+
+ def resolve(self, klass):
+ if self.encodings.has_key(klass):
+ return self.encodings[klass]
+ for base in klass.__bases__:
+ result = self.resolve(base)
+ if result != None:
+ return result
+
def read(self, n):
"""
reads in 'n' bytes from the stream. Can raise EOF exception
@@ -265,15 +304,14 @@
codec = Codec(enc, self.spec)
if tbl:
for key, value in tbl.items():
- if len(key) > 128:
+ if self.spec.major == 8 and self.spec.minor == 0 and len(key) > 128:
raise ValueError("field table key too long: '%s'" % key)
+ type = self.resolve(value.__class__)
+ if type == None:
+ raise ValueError("no encoding for: " + value.__class__)
codec.encode_shortstr(key)
- if isinstance(value, basestring):
- codec.write("S")
- codec.encode_longstr(value)
- else:
- codec.write("I")
- codec.encode_long(value)
+ codec.encode_octet(self.codes[type])
+ codec.encode(type, value)
s = enc.getvalue()
self.encode_long(len(s))
self.write(s)
@@ -287,13 +325,21 @@
result = {}
while self.nread - start < size:
key = self.decode_shortstr()
- type = self.read(1)
- if type == "S":
- value = self.decode_longstr()
- elif type == "I":
- value = self.decode_long()
+ code = self.decode_octet()
+ if self.types.has_key(code):
+ value = self.decode(self.types[code])
else:
- raise ValueError(repr(type))
+ w = width(code)
+ if fixed(code):
+ value = self.read(w)
+ elif w == 1:
+ value = self.decode_shortstr()
+ elif w == 2:
+ value = self.dec_str("!H")
+ elif w == 4:
+ value = self.decode_longstr()
+ else:
+ raise ValueError("illegal width: " + w)
result[key] = value
return result
@@ -390,3 +436,27 @@
codec = Codec(StringIO(self.decode_longstr()), self.spec)
type = self.spec.structs[codec.decode_short()]
return codec.decode_struct(type)
+
+def fixed(code):
+ return (code >> 6) != 2
+
+def width(code):
+ # decimal
+ if code >= 192:
+ decsel = (code >> 4) & 3
+ if decsel == 0:
+ return 5
+ elif decsel == 1:
+ return 9
+ elif decsel == 3:
+ return 0
+ else:
+ raise ValueError(code)
+ # variable width
+ elif code < 192 and code >= 128:
+ lenlen = (self.code >> 4) & 3
+ if lenlen == 3: raise ValueError(code)
+ return 2 ** lenlen
+ # fixed width
+ else:
+ return (self.code >> 4) & 7
Modified: incubator/qpid/trunk/qpid/python/qpid/spec.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/qpid/spec.py?rev=580122&r1=580121&r2=580122&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/python/qpid/spec.py (original)
+++ incubator/qpid/trunk/qpid/python/qpid/spec.py Thu Sep 27 11:56:23 2007
@@ -348,9 +348,10 @@
# constants
for nd in root.query["constant"]:
val = nd["@value"]
- if val.startswith("0x"): continue
- const = Constant(spec, pythonize(nd["@name"]), int(val),
- nd["@class"], get_docs(nd))
+ if val.startswith("0x"): val = int(val, 16)
+ else: val = int(val)
+ const = Constant(spec, pythonize(nd["@name"]), val, nd["@class"],
+ get_docs(nd))
try:
spec.constants.add(const)
except ValueError, e:
Modified: incubator/qpid/trunk/qpid/python/tests/codec.py
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/python/tests/codec.py?rev=580122&r1=580121&r2=580122&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/python/tests/codec.py (original)
+++ incubator/qpid/trunk/qpid/python/tests/codec.py Thu Sep 27 11:56:23 2007
@@ -442,13 +442,6 @@
"""
self.failUnlessEqual(self.callFunc('encode_table', {'$key1':'value1'}), '\x00\x00\x00\x11\x05$key1S\x00\x00\x00\x06value1', 'valid name value pair encoding FAILED...')
- # ----------------------------------------------------
- def test_field_table_invalid_field_name_length(self):
- """
- field names can have a maximum length of 128 chars
- """
- self.failUnlessRaises(Exception, self.codec.encode_table, {'x'*129:'value1'})
-
# ---------------------------------------------------
def test_field_table_multiple_name_value_pair(self):
"""