summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--viewstate/parse.py118
1 files changed, 70 insertions, 48 deletions
diff --git a/viewstate/parse.py b/viewstate/parse.py
index 75b82a5..a693c68 100644
--- a/viewstate/parse.py
+++ b/viewstate/parse.py
@@ -4,6 +4,7 @@ from .exceptions import ViewStateException
class ParserMeta(type):
+
def __init__(cls, name, bases, namespace):
super(ParserMeta, cls).__init__(name, bases, namespace)
if not hasattr(cls, 'registry'):
@@ -17,7 +18,9 @@ class ParserMeta(type):
class Parser(metaclass=ParserMeta):
- def parse(self, b):
+
+ @staticmethod
+ def parse(b):
marker, remain = b[0], b[1:]
try:
return Parser.registry[marker]().parse(remain)
@@ -26,6 +29,7 @@ class Parser(metaclass=ParserMeta):
class Const(Parser):
+
def parse(self, remain):
return self.const, remain
@@ -58,7 +62,8 @@ class FalseConst(Const):
class Integer(Parser):
marker = 0x02
- def parse(self, b):
+ @staticmethod
+ def parse(b):
n = 0
bits = 0
i = 0
@@ -75,9 +80,10 @@ class Integer(Parser):
class String(Parser):
marker = (0x05, 0x1e)
- def parse(self, b):
+ @staticmethod
+ def parse(b):
n = b[0]
- n, remain = Integer().parse(b)
+ n, remain = Integer.parse(b)
s = remain[:n]
return s.decode(), remain[n:]
@@ -85,12 +91,13 @@ class String(Parser):
class Enum(Parser):
marker = 0x0b
- def parse(self, b):
+ @staticmethod
+ def parse(b):
if b[0] in (0x29, 0x2a):
- enum, remain = String().parse(b[1:])
+ enum, remain = String.parse(b[1:])
elif b[0] == 0x2b:
- enum, remain = Integer().parse(b[1:])
- val, remain = Integer().parse(remain) # unsure about this part
+ enum, remain = Integer.parse(b[1:])
+ val, remain = Integer.parse(remain) # unsure about this part
final = 'Enum: {}, val: {}'.format(enum, val)
return final, remain
@@ -98,7 +105,8 @@ class Enum(Parser):
class Color(Parser):
marker = 0x0a
- def parse(self, b):
+ @staticmethod
+ def parse(b):
# No specification for color parsing, we're assuming it's just two bytes
# One example we have is that `\n\x91\x01` is parsed as `Color: Color [Salmon]`
# Originally reported in https://github.com/yuvadm/viewstate/issues/2
@@ -108,26 +116,29 @@ class Color(Parser):
class Pair(Parser):
marker = 0x0f
- def parse(self, b):
- first, remain = Parser().parse(b)
- second, remain = Parser().parse(remain)
+ @staticmethod
+ def parse(b):
+ first, remain = Parser.parse(b)
+ second, remain = Parser.parse(remain)
return (first, second), remain
class Triplet(Parser):
marker = 0x10
- def parse(self, b):
- first, remain = Parser().parse(b)
- second, remain = Parser().parse(remain)
- third, remain = Parser().parse(remain)
+ @staticmethod
+ def parse(b):
+ first, remain = Parser.parse(b)
+ second, remain = Parser.parse(remain)
+ third, remain = Parser.parse(remain)
return (first, second, third), remain
class Datetime(Parser):
marker = 0x06
- def parse(self, b):
+ @staticmethod
+ def parse(b):
#print([x for x in b[:8]])
return datetime(2000, 1, 1), b[8:]
@@ -135,7 +146,8 @@ class Datetime(Parser):
class Unit(Parser):
marker = 0x1b
- def parse(self, b):
+ @staticmethod
+ def parse(b):
#print([x for x in b[:12]])
return 'Unit: ', b[12:]
@@ -143,21 +155,23 @@ class Unit(Parser):
class RGBA(Parser):
marker = 0x09
- def parse(self, b):
+ @staticmethod
+ def parse(b):
return 'RGBA({},{},{},{})'.format(*b[:4]), b[4:]
class StringArray(Parser):
marker = 0x15
- def parse(self, b):
- n, remain = Integer().parse(b)
+ @staticmethod
+ def parse(b):
+ n, remain = Integer.parse(b)
l = []
for _ in range(n):
if not remain[0]:
val, remain = '', remain[1:]
else:
- val, remain = String().parse(remain)
+ val, remain = String.parse(remain)
l.append(val)
return l, remain
@@ -165,11 +179,12 @@ class StringArray(Parser):
class Array(Parser):
marker = 0x16
- def parse(self, b):
- n, remain = Integer().parse(b)
+ @staticmethod
+ def parse(b):
+ n, remain = Integer.parse(b)
l = []
for _ in range(n):
- val, remain = Parser().parse(remain)
+ val, remain = Parser.parse(remain)
l.append(val)
return l, remain
@@ -177,22 +192,24 @@ class Array(Parser):
class StringRef(Parser):
marker = 0x1f
- def parse(self, b):
- val, remain = Integer().parse(b)
+ @staticmethod
+ def parse(b):
+ val, remain = Integer.parse(b)
return 'Stringref #{}'.format(val), remain
class FormattedString(Parser):
marker = 0x28
- def parse(self, b):
+ @staticmethod
+ def parse(b):
if b[0] == 0x29:
- s1, remain = String().parse(b[1:])
- s2, remain = String().parse(remain)
+ s1, remain = String.parse(b[1:])
+ s2, remain = String.parse(remain)
return 'Formatted string: {} {}'.format(s2, s1), remain
elif b[0] == 0x2b:
- i, remain = Integer().parse(b[1:])
- s, remain = String().parse(remain)
+ i, remain = Integer.parse(b[1:])
+ s, remain = String.parse(remain)
return 'Formatted string: {} type ref {}'.format(s, i), remain
else:
raise ViewStateException('Unknown formatted string type marker {}'.format(b[:20]))
@@ -201,14 +218,15 @@ class FormattedString(Parser):
class SparseArray(Parser):
marker = 0x3c
- def parse(self, b):
- type, remain = Type().parse(b)
- length, remain = Integer().parse(remain)
- n, remain = Integer().parse(remain)
+ @staticmethod
+ def parse(b):
+ type, remain = Type.parse(b)
+ length, remain = Integer.parse(remain)
+ n, remain = Integer.parse(remain)
l = [None] * length
for _ in range(n):
- idx, remain = Integer().parse(remain)
- val, remain = Parser().parse(remain)
+ idx, remain = Integer.parse(remain)
+ val, remain = Parser.parse(remain)
l[idx] = val
return l, remain
@@ -216,33 +234,37 @@ class SparseArray(Parser):
class Dict(Parser):
marker = 0x18
- def parse(self, b):
+ @staticmethod
+ def parse(b):
n = b[0]
d = {}
remain = b[1:]
for _ in range(n):
- k, remain = Parser().parse(remain)
- v, remain = Parser().parse(remain)
+ k, remain = Parser.parse(remain)
+ v, remain = Parser.parse(remain)
d[k] = v
return d, remain
class Type(Parser):
- def parse(self, b):
+
+ @staticmethod
+ def parse(b):
if b[0] in (0x29, 0x2a):
- return String().parse(b[1:])
+ return String.parse(b[1:])
elif b[0] == 0x2b:
- return Integer().parse(b[1:])
+ return Integer.parse(b[1:])
else:
raise ViewStateException('Unknown type flag at {} bytes {}'.format(len(b), b[:20]))
class TypedArray(Parser):
marker = 0x14
- def parse(self, b):
- typeval, remain = Type().parse(b)
- n, remain = Integer().parse(remain)
+ @staticmethod
+ def parse(b):
+ typeval, remain = Type.parse(b)
+ n, remain = Integer.parse(remain)
l = []
for _ in range(n):
- val, remain = Parser().parse(remain)
+ val, remain = Parser.parse(remain)
l.append(val)
return l, remain