From bfc9b7a416450e72b6309fcaf41ec102f7dc2901 Mon Sep 17 00:00:00 2001 From: Yuval Adam <_@yuv.al> Date: Wed, 28 Mar 2018 23:48:16 +0200 Subject: Some level of metaprogramming is working --- tests/test_parse.py | 12 ++++++++---- viewstate/parse.py | 51 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/tests/test_parse.py b/tests/test_parse.py index 56f36c9..1a83ac5 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -6,15 +6,19 @@ from os.path import join from viewstate import * -class TestParse(object): +class TestNewParse(object): + def test_const_value(self): + vs = ViewState(raw=b'\xff\x01\x67') + assert vs.decode() is True def test_int_value(self): vs = ViewState(raw=b'\xff\x01\x02\x88\x01') assert vs.decode() == 136 - def test_const_value(self): - vs = ViewState(raw=b'\xff\x01\x67') - assert vs.decode() is True +@pytest.mark.skip() +class TestParse(object): + + def test_string_value(self): s = 'abcdefghij' diff --git a/viewstate/parse.py b/viewstate/parse.py index 66573a2..5b4aa55 100644 --- a/viewstate/parse.py +++ b/viewstate/parse.py @@ -3,33 +3,45 @@ from datetime import datetime from .exceptions import ViewStateException -class ViewStateParser(object): - def get_subparsers(self): - return {c.marker: c for c in self.__class__.__subclasses__()} +class ViewStateParserMeta(type): + def __init__(cls, name, bases, namespace): + super(ViewStateParserMeta, cls).__init__(name, bases, namespace) + if not hasattr(cls, 'registry'): + cls.registry = {} + if hasattr(cls, 'marker'): + print('registry', cls) + cls.registry[getattr(cls, 'marker')] = cls + + +class ViewStateParser(metaclass=ViewStateParserMeta): def parse(self, b): - SUBPARSERS = self.get_subparsers() marker, *remain = b try: - return SUBPARSERS[marker]().parse(remain) + return ViewStateParser.registry[marker]().parse(remain) except KeyError: raise ViewStateException('Unknown marker') -class Const(object): - def parse(self): - return self.const, self.remain +class Const(ViewStateParser): + def parse(self, remain): + return self.const, remain + + +class TrueConst(Const): + marker = 0x67 + const = True -class NoneConst(ViewStateParser) CONSTS = { - 100: None, - 101: '', - 102: 0, - 103: True, - 104: False + 0x64: None, + 0x65: '', + 0x66: 0, + 0x67: True, + 0x68: False } + def parse_const(b): return CONSTS.get(b, None) @@ -81,10 +93,13 @@ class Color(ViewStateParser): # Originally reported in https://github.com/yuvadm/viewstate/issues/2 return 'Color: unknown', b[2:] -def parse_pair(b): - first, remain = parse(b) - second, remain = parse(remain) - return (first, second), remain +class Pair(ViewStateParser): + marker = 0x0f + + def parse(self, b): + first, remain = parse(b) + second, remain = parse(remain) + return (first, second), remain def parse_triplet(b): first, remain = parse(b) -- cgit v1.3.1