82 interpret the part payload. |
82 interpret the part payload. |
83 |
83 |
84 The binary format of the header is has follow |
84 The binary format of the header is has follow |
85 |
85 |
86 :typesize: (one byte) |
86 :typesize: (one byte) |
|
87 |
87 :typename: alphanumerical part name |
88 :typename: alphanumerical part name |
88 :option: we do not support option yet this denoted by two 16 bites zero. |
89 |
|
90 :parameters: |
|
91 |
|
92 Part's parameter may have arbitraty content, the binary structure is:: |
|
93 |
|
94 <mandatory-count><advisory-count><param-sizes><param-data> |
|
95 |
|
96 :mandatory-count: 1 byte, number of mandatory parameters |
|
97 |
|
98 :advisory-count: 1 byte, number of advisory parameters |
|
99 |
|
100 :param-sizes: |
|
101 |
|
102 N couple of bytes, where N is the total number of parameters. Each |
|
103 couple contains (<size-of-key>, <size-of-value) for one parameter. |
|
104 |
|
105 :param-data: |
|
106 |
|
107 A blob of bytes from which each parameter key and value can be |
|
108 retrieved using the list of size couples stored in the previous |
|
109 field. |
|
110 |
|
111 Mandatory parameters comes first, then the advisory ones. |
89 |
112 |
90 :payload: |
113 :payload: |
91 |
114 |
92 payload is a series of `<chunksize><chunkdata>`. |
115 payload is a series of `<chunksize><chunkdata>`. |
93 |
116 |
261 self._offset = offset + size |
293 self._offset = offset + size |
262 return data |
294 return data |
263 typesize = _unpack(_fparttypesize, fromheader(1))[0] |
295 typesize = _unpack(_fparttypesize, fromheader(1))[0] |
264 parttype = fromheader(typesize) |
296 parttype = fromheader(typesize) |
265 self.ui.debug('part type: "%s"\n' % parttype) |
297 self.ui.debug('part type: "%s"\n' % parttype) |
266 assert fromheader(2) == '\0\0' # no option for now |
298 ## reading parameters |
|
299 # param count |
|
300 mancount, advcount = _unpack(_fpartparamcount, fromheader(2)) |
|
301 self.ui.debug('part parameters: %i\n' % (mancount + advcount)) |
|
302 # param size |
|
303 paramsizes = _unpack(_makefpartparamsizes(mancount + advcount), |
|
304 fromheader(2*(mancount + advcount))) |
|
305 # make it a list of couple again |
|
306 paramsizes = zip(paramsizes[::2], paramsizes[1::2]) |
|
307 # split mandatory from advisory |
|
308 mansizes = paramsizes[:mancount] |
|
309 advsizes = paramsizes[mancount:] |
|
310 # retrive param value |
|
311 manparams = [] |
|
312 for key, value in mansizes: |
|
313 manparams.append((fromheader(key), fromheader(value))) |
|
314 advparams = [] |
|
315 for key, value in advsizes: |
|
316 advparams.append((fromheader(key), fromheader(value))) |
267 del self._offset # clean up layer, nobody saw anything. |
317 del self._offset # clean up layer, nobody saw anything. |
268 self.ui.debug('part parameters: 0\n') |
318 ## part payload |
269 payload = [] |
319 payload = [] |
270 payloadsize = self._unpack(_fpayloadsize)[0] |
320 payloadsize = self._unpack(_fpayloadsize)[0] |
271 self.ui.debug('payload chunk size: %i\n' % payloadsize) |
321 self.ui.debug('payload chunk size: %i\n' % payloadsize) |
272 while payloadsize: |
322 while payloadsize: |
273 payload.append(self._readexact(payloadsize)) |
323 payload.append(self._readexact(payloadsize)) |
274 payloadsize = self._unpack(_fpayloadsize)[0] |
324 payloadsize = self._unpack(_fpayloadsize)[0] |
275 self.ui.debug('payload chunk size: %i\n' % payloadsize) |
325 self.ui.debug('payload chunk size: %i\n' % payloadsize) |
276 payload = ''.join(payload) |
326 payload = ''.join(payload) |
277 current = part(parttype, data=payload) |
327 current = part(parttype, manparams, advparams, data=payload) |
278 return current |
328 return current |
279 |
329 |
280 |
330 |
281 class part(object): |
331 class part(object): |
282 """A bundle2 part contains application level payload |
332 """A bundle2 part contains application level payload |
283 |
333 |
284 The part `type` is used to route the part to the application level |
334 The part `type` is used to route the part to the application level |
285 handler. |
335 handler. |
286 """ |
336 """ |
287 |
337 |
288 def __init__(self, parttype, data=''): |
338 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(), |
|
339 data=''): |
289 self.type = parttype |
340 self.type = parttype |
290 self.data = data |
341 self.data = data |
|
342 self.mandatoryparams = mandatoryparams |
|
343 self.advisoryparams = advisoryparams |
291 |
344 |
292 def getchunks(self): |
345 def getchunks(self): |
293 ### header |
346 #### header |
|
347 ## parttype |
294 header = [_pack(_fparttypesize, len(self.type)), |
348 header = [_pack(_fparttypesize, len(self.type)), |
295 self.type, |
349 self.type, |
296 '\0\0', # No option support for now. |
|
297 ] |
350 ] |
|
351 ## parameters |
|
352 # count |
|
353 manpar = self.mandatoryparams |
|
354 advpar = self.advisoryparams |
|
355 header.append(_pack(_fpartparamcount, len(manpar), len(advpar))) |
|
356 # size |
|
357 parsizes = [] |
|
358 for key, value in manpar: |
|
359 parsizes.append(len(key)) |
|
360 parsizes.append(len(value)) |
|
361 for key, value in advpar: |
|
362 parsizes.append(len(key)) |
|
363 parsizes.append(len(value)) |
|
364 paramsizes = _pack(_makefpartparamsizes(len(parsizes) / 2), *parsizes) |
|
365 header.append(paramsizes) |
|
366 # key, value |
|
367 for key, value in manpar: |
|
368 header.append(key) |
|
369 header.append(value) |
|
370 for key, value in advpar: |
|
371 header.append(key) |
|
372 header.append(value) |
|
373 ## finalize header |
298 headerchunk = ''.join(header) |
374 headerchunk = ''.join(header) |
299 yield _pack(_fpartheadersize, len(headerchunk)) |
375 yield _pack(_fpartheadersize, len(headerchunk)) |
300 yield headerchunk |
376 yield headerchunk |
|
377 ## payload |
301 # we only support fixed size data now. |
378 # we only support fixed size data now. |
302 # This will be improved in the future. |
379 # This will be improved in the future. |
303 if len(self.data): |
380 if len(self.data): |
304 yield _pack(_fpayloadsize, len(self.data)) |
381 yield _pack(_fpayloadsize, len(self.data)) |
305 yield self.data |
382 yield self.data |
306 # end of payload |
383 # end of payload |
307 yield _pack(_fpayloadsize, 0) |
384 yield _pack(_fpayloadsize, 0) |
308 |
385 |
309 |
|