[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Replace Pack enum with a Size class
commit a615cf7bc392337cc4353885ab64530abeae3dcc
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Thu Jan 11 11:56:32 2018 -0800
Replace Pack enum with a Size class
Swapping our enum with the class so it can both pack and unpack.
---
stem/client/__init__.py | 72 ++++++++++++++++++++++++++++++++++++++++---------
stem/client/cell.py | 11 ++++----
2 files changed, 65 insertions(+), 18 deletions(-)
diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 21786835..d0920778 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -28,29 +28,77 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
::
- Relay - Connection with a relay's ORPort.
+ Size - Packable and unpackable field size.
+ |- pack - encodes content
+ |- unpack - decodes content
+ +- pop - decodes content with remainder
"""
-from stem.util import enum
+import struct
ZERO = '\x00'
-
__all__ = [
'cell',
]
-class Relay(object):
+class Size(object):
"""
- Connection with a `Tor relay's ORPort
- <https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt>`_.
+ Unsigned `struct.pack format
+ <https://docs.python.org/2/library/struct.html#format-characters>` for
+ network-order fields.
"""
+ def __init__(self, name, size, pack_format):
+ self.name = name
+ self.size = size
+ self.format = pack_format
+
+ def pack(self, content):
+ """
+ Encodes bytes into a packed field.
+
+ :param bytes content: content to encode
+
+ :raises: **ValueError** if content isn't of the right size
+ """
+
+ unpacked = struct.pack(self.format, content)
+
+ if self.size != len(unpacked):
+ raise ValueError("'%s' is the wrong size for a %s field" % (unpacked, self.name))
+
+ return unpacked
+
+ def unpack(self, content):
+ """
+ Decodes packed data into bytes.
+
+ :param bytes content: content to encode
+
+ :raises: **ValueError** if packed data isn't of the right size
+ """
+
+ if self.size != len(content):
+ raise ValueError("'%s' is the wrong size for a %s field" % (content, self.name))
+
+ return struct.unpack(self.format, content)[0]
+
+ def pop(self, content):
+ """
+ Decodes the first characters as this data type, providing it and the
+ remainder.
+
+ :param bytes content: content to encode
+
+ :raises: **ValueError** if packed data isn't of the right size
+ """
+
+ return self.unpack(content[:self.size]), content[self.size:]
+
-Pack = enum.Enum(
- ('CHAR', '!B'), # 1 byte
- ('SHORT', '!H'), # 2 bytes
- ('LONG', '!L'), # 4 bytes
- ('LONG_LONG', '!Q'), # 8 bytes
-)
+setattr(Size, 'CHAR', Size('CHAR', 1, '!B'))
+setattr(Size, 'SHORT', Size('SHORT', 2, '!H'))
+setattr(Size, 'LONG', Size('LONG', 4, '!L'))
+setattr(Size, 'LONG_LONG', Size('LONG_LONG', 8, '!Q'))
diff --git a/stem/client/cell.py b/stem/client/cell.py
index 7c680c4e..42fe87e1 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -38,11 +38,10 @@ Messages communicated over a Tor relay's ORPort.
import collections
import inspect
-import struct
import sys
from stem import UNDEFINED
-from stem.client import ZERO, Pack
+from stem.client import ZERO, Size
class Cell(collections.namedtuple('Cell', ['name', 'value', 'fixed_size', 'for_circuit'])):
@@ -124,9 +123,9 @@ class Cell(collections.namedtuple('Cell', ['name', 'value', 'fixed_size', 'for_c
:raise: **ValueError** if cell type invalid or payload is too large
"""
- packed_circ_id = struct.pack(Pack.LONG if link_version > 3 else Pack.SHORT, circ_id)
- packed_command = struct.pack(Pack.CHAR, cls.VALUE)
- packed_size = b'' if cls.IS_FIXED_SIZE else struct.pack(Pack.SHORT, len(payload))
+ packed_circ_id = Size.LONG.pack(circ_id) if link_version > 3 else Size.SHORT.pack(circ_id)
+ packed_command = Size.CHAR.pack(cls.VALUE)
+ packed_size = b'' if cls.IS_FIXED_SIZE else Size.SHORT.pack(len(payload))
cell = b''.join((packed_circ_id, packed_command, packed_size, payload))
# pad fixed sized cells to the required length
@@ -249,7 +248,7 @@ class VersionsCell(Cell):
# Used for link version negotiation so we don't have that yet. This is fine
# since VERSION cells avoid most version dependent attributes.
- payload = b''.join([struct.pack(Pack.SHORT, v) for v in versions])
+ payload = b''.join([Size.SHORT.pack(v) for v in versions])
return cls._pack(3, payload)
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits