forked from scut-ray/py-yyp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
yyp_unmarshal.py
122 lines (100 loc) · 3.5 KB
/
yyp_unmarshal.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#coding: utf8
__author__ = 'liangguanhui@qq.com'
import struct, StringIO
from __init__ import *
from yyp_utils import readfull
class YYPUnMarshal(object):
def __init__(self, input):
if isinstance(input, str):
self._in = StringIO.StringIO(input)
elif hasattr(input, 'read'):
self._in = input
else:
raise YYPException("not match input type! %s" % type(input))
def pop(self, type):
if (type == YYP_INT8):
buf = readfull(self._in, 1)
return struct.unpack('<b', buf)[0]
elif (type == YYP_INT16):
buf = readfull(self._in, 2)
return struct.unpack('<h', buf)[0]
elif (type == YYP_INT32):
buf = readfull(self._in, 4)
return struct.unpack('<i', buf)[0]
elif (type == YYP_INT64):
buf = readfull(self._in, 8)
return struct.unpack('<q', buf)[0]
elif (type == YYP_UINT8):
buf = readfull(self._in, 1)
return struct.unpack('<B', buf)[0]
elif (type == YYP_UINT16):
buf = readfull(self._in, 2)
return struct.unpack('<H', buf)[0]
elif (type == YYP_UINT32):
buf = readfull(self._in, 4)
return struct.unpack('<I', buf)[0]
elif (type == YYP_UINT64):
buf = readfull(self._in, 8)
return struct.unpack('<Q', buf)[0]
elif (type == YYP_FLOAT32):
buf = readfull(self._in, 4)
return struct.unpack('<f', buf)[0]
elif (type == YYP_FLOAT64):
buf = readfull(self._in, 8)
return struct.unpack('<d', buf)[0]
elif (type == YYP_STRING16):
buf = readfull(self._in, 2)
l = struct.unpack('<H', buf)[0]
if l <= 0:
return ""
return readfull(self._in, l)
elif (type == YYP_STRING32):
buf = readfull(self._in, 4)
l = struct.unpack('<I', buf)[0]
if l <= 0:
return ""
return readfull(self._in, l)
else:
raise YYPException("Invalid type %s" % type)
def popInt8(self):
return self.pop(YYP_INT8)
def popInt16(self):
return self.pop(YYP_INT16)
def popInt32(self):
return self.pop(YYP_INT32)
def popInt64(self):
return self.pop(YYP_INT64)
def popUInt8(self):
return self.pop(YYP_UINT8)
def popUInt16(self):
return self.pop(YYP_UINT16)
def popUInt32(self):
return self.pop(YYP_UINT32)
def popUInt64(self):
return self.pop(YYP_UINT64)
def popFloat32(self):
return self.pop(YYP_FLOAT32)
def popFloat64(self):
return self.pop(YYP_FLOAT64)
def popString16(self):
return self.pop(YYP_STRING16)
def popString32(self):
return self.pop(YYP_STRING32)
def popList(self, type):
l = self.popUInt32()
ret = []
for i in range(l):
ret.append(self.pop(type))
return ret
def popStringList(self):
return self.popList(YYP_STRING16)
def popDict(self, keytype, valuetype):
l = self.popUInt32()
ret = {}
for i in range(l):
key = self.pop(keytype)
value = self.pop(valuetype)
ret[key] = value
return ret
def popStringDict(self):
return self.popDict(YYP_STRING16, YYP_STRING16)