mercurial/bundle2.py
changeset 21024 7731a2281cf0
parent 21020 5041163ee382
child 21060 0bea9db7543b
equal deleted inserted replaced
21023:57b50abe2b24 21024:7731a2281cf0
    22  - end of stream marker.
    22  - end of stream marker.
    23 
    23 
    24 the Binary format
    24 the Binary format
    25 ============================
    25 ============================
    26 
    26 
    27 All numbers are unsigned and big endian.
    27 All numbers are unsigned and big-endian.
    28 
    28 
    29 stream level parameters
    29 stream level parameters
    30 ------------------------
    30 ------------------------
    31 
    31 
    32 Binary format is as follow
    32 Binary format is as follow
    38 :params value: arbitrary number of Bytes
    38 :params value: arbitrary number of Bytes
    39 
    39 
    40   A blob of `params size` containing the serialized version of all stream level
    40   A blob of `params size` containing the serialized version of all stream level
    41   parameters.
    41   parameters.
    42 
    42 
    43   The blob contains a space separated list of parameters. parameter with value
    43   The blob contains a space separated list of parameters. Parameters with value
    44   are stored in the form `<name>=<value>`. Both name and value are urlquoted.
    44   are stored in the form `<name>=<value>`. Both name and value are urlquoted.
    45 
    45 
    46   Empty name are obviously forbidden.
    46   Empty name are obviously forbidden.
    47 
    47 
    48   Name MUST start with a letter. If this first letter is lower case, the
    48   Name MUST start with a letter. If this first letter is lower case, the
    49   parameter is advisory and can be safefly ignored. However when the first
    49   parameter is advisory and can be safely ignored. However when the first
    50   letter is capital, the parameter is mandatory and the bundling process MUST
    50   letter is capital, the parameter is mandatory and the bundling process MUST
    51   stop if he is not able to proceed it.
    51   stop if he is not able to proceed it.
    52 
    52 
    53   Stream parameters use a simple textual format for two main reasons:
    53   Stream parameters use a simple textual format for two main reasons:
    54 
    54 
    55   - Stream level parameters should remains simple and we want to discourage any
    55   - Stream level parameters should remain simple and we want to discourage any
    56     crazy usage.
    56     crazy usage.
    57   - Textual data allow easy human inspection of a the bundle2 header in case of
    57   - Textual data allow easy human inspection of a bundle2 header in case of
    58     troubles.
    58     troubles.
    59 
    59 
    60   Any Applicative level options MUST go into a bundle2 part instead.
    60   Any Applicative level options MUST go into a bundle2 part instead.
    61 
    61 
    62 Payload part
    62 Payload part
    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 
    88     :typename: alphanumerical part name
    88     :parttype: alphanumerical part name
    89 
    89 
    90     :partid: A 32bits integer (unique in the bundle) that can be used to refer
    90     :partid: A 32bits integer (unique in the bundle) that can be used to refer
    91              to this part.
    91              to this part.
    92 
    92 
    93     :parameters:
    93     :parameters:
    94 
    94 
    95         Part's parameter may have arbitraty content, the binary structure is::
    95         Part's parameter may have arbitrary content, the binary structure is::
    96 
    96 
    97             <mandatory-count><advisory-count><param-sizes><param-data>
    97             <mandatory-count><advisory-count><param-sizes><param-data>
    98 
    98 
    99         :mandatory-count: 1 byte, number of mandatory parameters
    99         :mandatory-count: 1 byte, number of mandatory parameters
   100 
   100 
   119 
   119 
   120     `chunksize` is a 32 bits integer, `chunkdata` are plain bytes (as much as
   120     `chunksize` is a 32 bits integer, `chunkdata` are plain bytes (as much as
   121     `chunksize` says)` The payload part is concluded by a zero size chunk.
   121     `chunksize` says)` The payload part is concluded by a zero size chunk.
   122 
   122 
   123     The current implementation always produces either zero or one chunk.
   123     The current implementation always produces either zero or one chunk.
   124     This is an implementation limitation that will ultimatly be lifted.
   124     This is an implementation limitation that will ultimately be lifted.
   125 
   125 
   126 Bundle processing
   126 Bundle processing
   127 ============================
   127 ============================
   128 
   128 
   129 Each part is processed in order using a "part handler". Handler are registered
   129 Each part is processed in order using a "part handler". Handler are registered
   191 
   191 
   192 class unbundlerecords(object):
   192 class unbundlerecords(object):
   193     """keep record of what happens during and unbundle
   193     """keep record of what happens during and unbundle
   194 
   194 
   195     New records are added using `records.add('cat', obj)`. Where 'cat' is a
   195     New records are added using `records.add('cat', obj)`. Where 'cat' is a
   196     category of record and obj is an arbitraty object.
   196     category of record and obj is an arbitrary object.
   197 
   197 
   198     `records['cat']` will return all entries of this category 'cat'.
   198     `records['cat']` will return all entries of this category 'cat'.
   199 
   199 
   200     Iterating on the object itself will yield `('category', obj)` tuples
   200     Iterating on the object itself will yield `('category', obj)` tuples
   201     for all entries.
   201     for all entries.
   325 class bundle20(object):
   325 class bundle20(object):
   326     """represent an outgoing bundle2 container
   326     """represent an outgoing bundle2 container
   327 
   327 
   328     Use the `addparam` method to add stream level parameter. and `addpart` to
   328     Use the `addparam` method to add stream level parameter. and `addpart` to
   329     populate it. Then call `getchunks` to retrieve all the binary chunks of
   329     populate it. Then call `getchunks` to retrieve all the binary chunks of
   330     datathat compose the bundle2 container."""
   330     data that compose the bundle2 container."""
   331 
   331 
   332     def __init__(self, ui):
   332     def __init__(self, ui):
   333         self.ui = ui
   333         self.ui = ui
   334         self._params = []
   334         self._params = []
   335         self._parts = []
   335         self._parts = []
   343         self._params.append((name, value))
   343         self._params.append((name, value))
   344 
   344 
   345     def addpart(self, part):
   345     def addpart(self, part):
   346         """add a new part to the bundle2 container
   346         """add a new part to the bundle2 container
   347 
   347 
   348         Parts contains the actuall applicative payload."""
   348         Parts contains the actual applicative payload."""
   349         assert part.id is None
   349         assert part.id is None
   350         part.id = len(self._parts) # very cheap counter
   350         part.id = len(self._parts) # very cheap counter
   351         self._parts.append(part)
   351         self._parts.append(part)
   352 
   352 
   353     def getchunks(self):
   353     def getchunks(self):
   410             raise util.Abort(_('unknown bundle version %s') % version)
   410             raise util.Abort(_('unknown bundle version %s') % version)
   411         self.ui.debug('start processing of %s stream\n' % header)
   411         self.ui.debug('start processing of %s stream\n' % header)
   412 
   412 
   413     @util.propertycache
   413     @util.propertycache
   414     def params(self):
   414     def params(self):
   415         """dictionnary of stream level parameters"""
   415         """dictionary of stream level parameters"""
   416         self.ui.debug('reading bundle2 stream parameters\n')
   416         self.ui.debug('reading bundle2 stream parameters\n')
   417         params = {}
   417         params = {}
   418         paramssize = self._unpack(_fstreamparamsize)[0]
   418         paramssize = self._unpack(_fstreamparamsize)[0]
   419         if paramssize:
   419         if paramssize:
   420             for p in self._readexact(paramssize).split(' '):
   420             for p in self._readexact(paramssize).split(' '):