Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ea28bbd

Browse files
committed
Merge 9d2fb59 into 222130c
2 parents 222130c + 9d2fb59 commit ea28bbd

File tree

3 files changed

+58
-47
lines changed

3 files changed

+58
-47
lines changed

wcf/records/base.py

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -199,49 +199,73 @@ class ArrayRecord(Record):
199199
0xB1: ('UuidTextWithEndElement', 16, ''),
200200
}
201201

202-
def __init__(self, element, recordtype, data):
202+
def __init__(self, element, data, attributes):
203203
self.element = element
204-
self.recordtype = recordtype
205204
self.count = len(data)
206205
self.data = data
206+
recordtype = None
207+
for data in self.data:
208+
if recordtype is None:
209+
recordtype = data.type + 1
210+
else:
211+
assert recordtype == data.type + 1
212+
self.recordtype = recordtype
213+
self.attributes = []
207214

208215
def to_bytes(self):
209216
"""
217+
>>> from wcf.records.text import Int32TextRecord
210218
>>> from wcf.records.elements import ShortElementRecord
211-
>>> ArrayRecord(ShortElementRecord('item'), 0x8D, ['\\x01\\x00\\x00\\x00', '\\x02\\x00\\x00\\x00', '\\x03\\x00\\x00\\x00']).to_bytes()
219+
>>> ArrayRecord(ShortElementRecord('item'), [Int32TextRecord(1), Int32TextRecord(2), Int32TextRecord(3)], []).to_bytes()
212220
b'\\x03@\\x04item\\x01\\x8d\\x03\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
213221
"""
214222
bt = super(ArrayRecord, self).to_bytes()
215223
bt += self.element.to_bytes()
224+
for attrib in self.attributes:
225+
bt += attrib.to_bytes()
216226
bt += EndElementRecord().to_bytes()
217227
bt += bytes(struct.pack(b'<B', self.recordtype))
218228
bt += MultiByteInt31(self.count).to_bytes()
219229
for data in self.data:
220-
if isinstance(data, bytes):
221-
bt += data
222-
elif hasattr(data, 'to_bytes'):
223-
bt += data.to_bytes()
224-
else:
225-
bt += data.encode('latin1')
226-
230+
bt += data.to_bytes()[1:]
227231
return bytes(bt)
228232

229233
@classmethod
230234
def parse(cls, fp):
235+
"""
236+
>>> from wcf.records import *
237+
>>> from io import BytesIO
238+
>>> buf = BytesIO(b'@\\x04item\\x01\\x8d\\x03\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x03\\x00\\x00\\x00')
239+
>>> r = ArrayRecord.parse(buf)
240+
>>> r
241+
<ArrayRecord(type=0x3)>
242+
>>> r.to_bytes()
243+
b'\\x03@\\x04item\\x01\\x8d\\x03\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
244+
"""
231245
element = struct.unpack(b'<B', fp.read(1))[0]
232-
element = __records__[element].parse(fp)
246+
element = Record.records[element].parse(fp)
247+
attributes = []
248+
while True:
249+
type = struct.unpack(b'<B', fp.read(1))[0]
250+
obj = Record.records[type].parse(fp)
251+
if isinstance(obj, EndElementRecord):
252+
break
253+
elif isinstance(obj, Attribute):
254+
attributes.append(obj)
255+
else:
256+
raise ValueError('unknown type: %s' % hex(type))
233257
recordtype = struct.unpack(b'<B', fp.read(1))[0]
234258
count = MultiByteInt31.parse(fp).value
235259
data = []
236260
for i in range(count):
237-
data.append(__records__[recordtype-1].parse(fp))
238-
return cls(element, recordtype, data)
261+
data.append(Record.records[recordtype-1].parse(fp))
262+
return cls(element, data, attributes)
239263

240264
def __str__(self):
241265
"""
242266
>>> from wcf.records.elements import ShortElementRecord
243267
>>> from wcf.records.text import Int32TextRecord
244-
>>> str(ArrayRecord(ShortElementRecord('item'), 0x8D, [Int32TextRecord(1),Int32TextRecord(2),Int32TextRecord(3)]))
268+
>>> str(ArrayRecord(ShortElementRecord('item'), [Int32TextRecord(1), Int32TextRecord(2), Int32TextRecord(3)], []))
245269
'<item>1</item><item>2</item><item>3</item>'
246270
"""
247271
string = ''

wcf/records/text.py

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import datetime
3636
import logging
3737
import uuid
38-
import sys
3938

4039
try:
4140
from htmlentitydefs import codepoint2name
@@ -195,16 +194,10 @@ class UnicodeChars8TextRecord(Text):
195194
type = 0xB6
196195

197196
def __init__(self, string):
198-
if sys.version_info >= (3, 0, 0):
199-
if isinstance(string, str):
200-
self.value = string
201-
else:
202-
self.value = str(string)
197+
if isinstance(string, str):
198+
self.value = string
203199
else:
204-
if isinstance(string, unicode):
205-
self.value = string
206-
else:
207-
self.value = unicode(string)
200+
self.value = str(string)
208201

209202
def to_bytes(self):
210203
"""
@@ -458,16 +451,10 @@ class Chars8TextRecord(Text):
458451
type = 0x98
459452

460453
def __init__(self, value):
461-
if sys.version_info >= (3, 0, 0):
462-
if isinstance(value, str):
463-
self.value = value
464-
else:
465-
self.value = str(value)
454+
if isinstance(value, str):
455+
self.value = value
466456
else:
467-
if isinstance(value, unicode):
468-
self.value = value
469-
else:
470-
self.value = unicode(value)
457+
self.value = str(value)
471458

472459
def __str__(self):
473460
return escape(self.value)

wcf/xml2records.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def reset(self):
4848
def _parse_tag(self, tag):
4949
if ':' in tag:
5050
prefix = tag[:tag.find(':')]
51-
name = tag[tag.find(':')+1:]
51+
name = tag[tag.find(':')+1:]
5252

5353
if len(prefix) == 1:
5454
cls_name = 'Element' + prefix.upper() + 'Record'
@@ -86,7 +86,7 @@ def _store_data(self, data, end=False):
8686
self.last_record.childs.append(textrecord)
8787
#if end:
8888
# textrecord.type += 1
89-
89+
9090
def _parse_data(self, data):
9191
data = data.strip()
9292
b64 = False
@@ -160,24 +160,24 @@ def _parse_data(self, data):
160160

161161
base_diff = 62135596800.0
162162
dt = int((time.mktime(dt.timetuple()) - base) * 10 + ms)
163-
163+
164164
return DateTimeTextRecord(dt, tz)
165-
165+
166166
# text as fallback
167167
val = len(data)
168168
if val < 2**8:
169-
return Chars8TextRecord(data)
169+
return UnicodeChars8TextRecord(data)
170170
elif val < 2**16:
171-
return Chars16TextRecord(data)
171+
return UnicodeChars16TextRecord(data)
172172
elif val < 2**32:
173-
return Chars32TextRecord(data)
173+
return UnicodeChars32TextRecord(data)
174174

175175
def _parse_attr(self, name, value):
176176

177177
if ':' in name:
178178
prefix = name[:name.find(':')]
179179
name = name[name.find(':')+1:]
180-
180+
181181
if prefix == 'xmlns':
182182
if value in inverted_dict:
183183
return DictionaryXmlnsAttributeRecord(name,
@@ -215,25 +215,25 @@ def handle_starttag(self, tag, attrs):
215215
if self.data:
216216
self._store_data(self.data, False)
217217
self.data = None
218-
218+
219219
el = self._parse_tag(tag)
220220
for n, v in attrs:
221221
el.attributes.append(self._parse_attr(n, v))
222222
self.last_record.childs.append(el)
223223
el.parent = self.last_record
224224
self.last_record = el
225-
225+
226226
def handle_startendtag(self, tag, attrs):
227227
if self.data:
228228
self._store_data(self.data, False)
229229
self.data = None
230-
230+
231231
el = self._parse_tag(tag)
232232
for n, v in attrs:
233233
el.attributes.append(self._parse_attr(n, v))
234234
self.last_record.childs.append(el)
235235
#self.last_record.childs.append(EndElementRecord())
236-
236+
237237
def handle_endtag(self, tag):
238238
if self.data:
239239
self._store_data(self.data, True)
@@ -324,14 +324,14 @@ def parse(cls, data):
324324
else:
325325
raise ValueError("%s has an incompatible type %s" % (data,
326326
type(data)))
327-
327+
328328
p.feed(xml)
329329

330330
return p.records
331331

332332
if __name__ == '__main__':
333333
import sys
334-
334+
335335
fp = sys.stdin
336336

337337
if len(sys.argv) > 1:

0 commit comments

Comments
 (0)