[svn] commit: r58 - in /experiments/graff-ccapi/python: ISC/CC/message.py test.py
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Oct 5 18:57:58 UTC 2009
Author: mgraff
Date: Mon Oct 5 18:57:57 2009
New Revision: 58
Log:
decoding works
Modified:
experiments/graff-ccapi/python/ISC/CC/message.py
experiments/graff-ccapi/python/test.py
Modified: experiments/graff-ccapi/python/ISC/CC/message.py
==============================================================================
--- experiments/graff-ccapi/python/ISC/CC/message.py (original)
+++ experiments/graff-ccapi/python/ISC/CC/message.py Mon Oct 5 18:57:57 2009
@@ -33,19 +33,24 @@
_ITEM_LENGTH_MASK = 0x30
def to_wire(self, items):
- """Encode a dict into wire format"""
-
+ """Encode a dict into wire format.
+ >>> cc = Message()
+ ... wire = to_wire({"a": "b"})
+ """
ret = []
ret.append(struct.pack(">I", self.PROTOCOL_VERSION))
ret.append(self._encode_hash(items))
return (''.join(ret))
def _encode_tag(self, tag):
- """Encode a single tag. Private."""
-
- return(struct.pack(">B", len(tag)) + tag)
+ """Encode a single UTF-8 tag.
+ >>> cc = Message()
+ ... wire_partial = cc._encode_tag('this')
+ """
+ return(struct.pack(">B", len(str(tag))) + str(tag))
def _encode_length_and_type(self, data, datatype):
+ """Helper method to handle the length encoding in one place."""
if data == None:
return(struct.pack(">B", self._ITEM_NULL))
length = len(data)
@@ -59,45 +64,133 @@
return(struct.pack(">B I", datatype, length) + data)
def _pack_string(self, item):
+ """Pack a string (data) and its type/length prefix."""
return (self._encode_length_and_type(item, self._ITEM_DATA))
def _pack_array(self, item):
+ """Pack a list (array) and its type/length prefix."""
return (self._encode_length_and_type(self._encode_array(item),
self._ITEM_LIST))
def _pack_hash(self, item):
+ """Pack a dict (hash) and its type/length prefix."""
data = self._encode_hash(item)
return (self._encode_length_and_type(data, self._ITEM_HASH))
def _encode_string(self, item):
+ """Encode a string. More or less identity."""
return (item)
def _pack_nil(self):
+ """Encode a nil (NULL, None) item."""
return self._encode_length_and_type(None, None)
def _encode_item(self, item):
+ """Encode each item depending on its type"""
if item == None:
return (self._pack_nil())
- elif item.__class__ == dict:
+ elif type(item) == dict:
return (self._pack_hash(item))
- elif item.__class__ == list:
+ elif type(item) == list:
return (self._pack_array(item))
else:
return (self._pack_string(str(item)))
def _encode_array(self, item):
+ """Encode an array, where each value is encoded recursively"""
ret = []
for i in item:
ret.append(self._encode_item(i))
return (''.join(ret))
def _encode_hash(self, item):
+ """Encode a hash, where each value is encoded recursively"""
+
ret = []
for key, value in item.items():
ret.append(self._encode_tag(key))
ret.append(self._encode_item(value))
return (''.join(ret))
+ #
+ # decode methods
+ #
+
+ def from_wire(self, data):
+ if len(data) < 5:
+ raise DecodeError("Data is too short to decode")
+ wire_version, data = data[0:4], data[4:]
+ wire_version = struct.unpack(">I", wire_version)[0]
+ if wire_version != self.PROTOCOL_VERSION:
+ raise DecodeError("Incorrect protocol version")
+ return self._decode_hash(data)
+
+ def _decode_tag(self, data):
+ if len(data) < 1:
+ raise DecodeError("Data underrun while decoding")
+ length = struct.unpack(">B", data[0])[0]
+ if len(data) - 1 < length:
+ raise DecodeError("Data underrun while decoding")
+ return [data[1:length + 1], data[length + 1:]]
+
+ def _decode_item(self, data):
+ if len(data) < 1:
+ raise DecodeError("Data underrun while decoding")
+ type_and_length_format = struct.unpack(">B", data[0])[0]
+ item_type = type_and_length_format & self._ITEM_MASK
+ length_format = type_and_length_format & self._ITEM_LENGTH_MASK
+
+ if item_type == self._ITEM_NULL:
+ data = data[1:]
+ else:
+ if length_format == self._ITEM_LENGTH_8:
+ if len(data) - 1 < 1:
+ raise DecodeError("Data underrun while decoding")
+ length = struct.unpack(">B", data[1])[0]
+ data = data[2:]
+ elif length_format == self._ITEM_LENGTH_16:
+ if len(data) - 1 < 2:
+ raise DecodeError("Data underrun while decoding")
+ length = struct.unpack(">H", data[1:3])[0]
+ data = data[3:]
+ elif length_format == self._ITEM_LENGTH_32:
+ if len(data) - 1 < 4:
+ raise DecodeError("Data underrun while decoding")
+ length = struct.unpack(">I", data[1:5])[0]
+ data = data[5:]
+ if len(data) < length:
+ raise DecodeError("Data underrun while decoding")
+ item = data[0:length]
+ data = data[length:]
+
+ if item_type == self._ITEM_DATA:
+ value = item
+ elif item_type == self._ITEM_HASH:
+ value = self._decode_hash(item)
+ elif item_type == self._ITEM_LIST:
+ value = self._decode_array(item)
+ elif item_type == self._ITEM_NULL:
+ value = None
+ else:
+ raise DecodeError("Unknown item type in decode: %02x" % item_type)
+
+ return [value, data]
+
+ def _decode_hash(self, data):
+ ret = {}
+ while len(data) > 0:
+ tag, data = self._decode_tag(data)
+ value, data = self._decode_item(data)
+ ret[tag] = value
+ return ret
+
+ def _decode_array(self, data):
+ ret = []
+ while len(data) > 0:
+ value, data = self._decode_item(data)
+ ret.append(value)
+ return ret
+
if __name__ == "__main__":
import doctest
doctest.testmod()
Modified: experiments/graff-ccapi/python/test.py
==============================================================================
--- experiments/graff-ccapi/python/test.py (original)
+++ experiments/graff-ccapi/python/test.py Mon Oct 5 18:57:57 2009
@@ -8,3 +8,6 @@
"string": "samplestring" }
s = cc.to_wire(ss)
ISC.Util.hexdump(s)
+
+print(ss)
+print cc.from_wire(s)
More information about the bind10-changes
mailing list