@@ -199,49 +199,73 @@ class ArrayRecord(Record):
199
199
0xB1 : ('UuidTextWithEndElement' , 16 , '' ),
200
200
}
201
201
202
- def __init__ (self , element , recordtype , data ):
202
+ def __init__ (self , element , data , attributes ):
203
203
self .element = element
204
- self .recordtype = recordtype
205
204
self .count = len (data )
206
205
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 = []
207
214
208
215
def to_bytes (self ):
209
216
"""
217
+ >>> from wcf.records.text import Int32TextRecord
210
218
>>> 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()
212
220
b'\\ x03@\\ x04item\\ x01\\ x8d\\ x03\\ x01\\ x00\\ x00\\ x00\\ x02\\ x00\\ x00\\ x00\\ x03\\ x00\\ x00\\ x00'
213
221
"""
214
222
bt = super (ArrayRecord , self ).to_bytes ()
215
223
bt += self .element .to_bytes ()
224
+ for attrib in self .attributes :
225
+ bt += attrib .to_bytes ()
216
226
bt += EndElementRecord ().to_bytes ()
217
227
bt += bytes (struct .pack (b'<B' , self .recordtype ))
218
228
bt += MultiByteInt31 (self .count ).to_bytes ()
219
229
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 :]
227
231
return bytes (bt )
228
232
229
233
@classmethod
230
234
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
+ """
231
245
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 ))
233
257
recordtype = struct .unpack (b'<B' , fp .read (1 ))[0 ]
234
258
count = MultiByteInt31 .parse (fp ).value
235
259
data = []
236
260
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 )
239
263
240
264
def __str__ (self ):
241
265
"""
242
266
>>> from wcf.records.elements import ShortElementRecord
243
267
>>> 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)], [ ]))
245
269
'<item>1</item><item>2</item><item>3</item>'
246
270
"""
247
271
string = ''
0 commit comments