Exemple #1
0
    def _payloadchunks(self, chunknum=0):
        '''seek to specified chunk and start yielding data'''
        if len(self._chunkindex) == 0:
            assert chunknum == 0, 'Must start with chunk 0'
            self._chunkindex.append((0, super(unbundlepart, self).tell()))
        else:
            assert chunknum < len(self._chunkindex), \
                   'Unknown chunk %d' % chunknum
            super(unbundlepart, self).seek(self._chunkindex[chunknum][1])

        pos = self._chunkindex[chunknum][0]
        payloadsize = self._unpack(_fpayloadsize)[0]
        self.ui.debug('payload chunk size: %i\n' % payloadsize)
        while payloadsize:
            if payloadsize == flaginterrupt:
                # interruption detection, the handler will now read a
                # single part and process it.
                interrupthandler(self.ui, self._fp)()
            elif payloadsize < 0:
                msg = 'negative payload chunk size: %i' %  payloadsize
                raise error.BundleValueError(msg)
            else:
                result = self._readexact(payloadsize)
                chunknum += 1
                pos += payloadsize
                if chunknum == len(self._chunkindex):
                    self._chunkindex.append((pos,
                                             super(unbundlepart, self).tell()))
                yield result
            payloadsize = self._unpack(_fpayloadsize)[0]
            self.ui.debug('payload chunk size: %i\n' % payloadsize)
Exemple #2
0
def handlereplycaps(op, inpart):
    """Used to transmit unknown content error over the wire"""
    kwargs = {}
    parttype = inpart.params.get('parttype')
    if parttype is not None:
        kwargs['parttype'] = parttype
    params = inpart.params.get('params')
    if params is not None:
        kwargs['params'] = params.split('\0')

    raise error.BundleValueError(**kwargs)
Exemple #3
0
    def _readpartheader(self):
        """reads a part header size and return the bytes blob

        returns None if empty"""
        headersize = self._unpack(_fpartheadersize)[0]
        if headersize < 0:
            raise error.BundleValueError('negative part header size: %i' %
                                         headersize)
        self.ui.debug('part header size: %i\n' % headersize)
        if headersize:
            return self._readexact(headersize)
        return None
Exemple #4
0
 def payloadchunks():
     payloadsize = self._unpack(_fpayloadsize)[0]
     self.ui.debug('payload chunk size: %i\n' % payloadsize)
     while payloadsize:
         if payloadsize == flaginterrupt:
             # interruption detection, the handler will now read a
             # single part and process it.
             interrupthandler(self.ui, self._fp)()
         elif payloadsize < 0:
             msg = 'negative payload chunk size: %i' % payloadsize
             raise error.BundleValueError(msg)
         else:
             yield self._readexact(payloadsize)
         payloadsize = self._unpack(_fpayloadsize)[0]
         self.ui.debug('payload chunk size: %i\n' % payloadsize)
Exemple #5
0
 def params(self):
     """dictionary of stream level parameters"""
     self.ui.debug('reading bundle2 stream parameters\n')
     params = {}
     paramssize = self._unpack(_fstreamparamsize)[0]
     if paramssize < 0:
         raise error.BundleValueError('negative bundle param size: %i' %
                                      paramssize)
     if paramssize:
         for p in self._readexact(paramssize).split(' '):
             p = p.split('=', 1)
             p = [urllib.unquote(i) for i in p]
             if len(p) < 2:
                 p.append(None)
             self._processparam(*p)
             params[p[0]] = p[1]
     return params
Exemple #6
0
    def _processparam(self, name, value):
        """process a parameter, applying its effect if needed

        Parameter starting with a lower case letter are advisory and will be
        ignored when unknown.  Those starting with an upper case letter are
        mandatory and will this function will raise a KeyError when unknown.

        Note: no option are currently supported. Any input will be either
              ignored or failing.
        """
        if not name:
            raise ValueError('empty parameter name')
        if name[0] not in string.letters:
            raise ValueError('non letter first character: %r' % name)
        # Some logic will be later added here to try to process the option for
        # a dict of known parameter.
        if name[0].islower():
            self.ui.debug("ignoring unknown parameter %r\n" % name)
        else:
            raise error.BundleValueError(params=(name, ))
Exemple #7
0
def processbundle(repo, unbundler, transactiongetter=_notransaction):
    """This function process a bundle, apply effect to/from a repo

    It iterates over each part then searches for and uses the proper handling
    code to process the part. Parts are processed in order.

    This is very early version of this function that will be strongly reworked
    before final usage.

    Unknown Mandatory part will abort the process.
    """
    op = bundleoperation(repo, transactiongetter)
    # todo:
    # - replace this is a init function soon.
    # - exception catching
    unbundler.params
    iterparts = unbundler.iterparts()
    part = None
    try:
        for part in iterparts:
            parttype = part.type
            # part key are matched lower case
            key = parttype.lower()
            try:
                handler = parthandlermapping.get(key)
                if handler is None:
                    raise error.BundleValueError(parttype=key)
                op.ui.debug('found a handler for part %r\n' % parttype)
                unknownparams = part.mandatorykeys - handler.params
                if unknownparams:
                    unknownparams = list(unknownparams)
                    unknownparams.sort()
                    raise error.BundleValueError(parttype=key,
                                                 params=unknownparams)
            except error.BundleValueError, exc:
                if key != parttype:  # mandatory parts
                    raise
                op.ui.debug('ignoring unsupported advisory part %s\n' % exc)
                # consuming the part
                part.read()
                continue

            # handler is called outside the above try block so that we don't
            # risk catching KeyErrors from anything other than the
            # parthandlermapping lookup (any KeyError raised by handler()
            # itself represents a defect of a different variety).
            output = None
            if op.reply is not None:
                op.ui.pushbuffer(error=True)
                output = ''
            try:
                handler(op, part)
            finally:
                if output is not None:
                    output = op.ui.popbuffer()
            if output:
                outpart = op.reply.newpart('b2x:output', data=output)
                outpart.addparam('in-reply-to', str(part.id), mandatory=False)
            part.read()
    except Exception, exc:
        if part is not None:
            # consume the bundle content
            part.read()
        for part in iterparts:
            # consume the bundle content
            part.read()
        # Small hack to let caller code distinguish exceptions from bundle2
        # processing fron the ones from bundle1 processing. This is mostly
        # needed to handle different return codes to unbundle according to the
        # type of bundle. We should probably clean up or drop this return code
        # craziness in a future version.
        exc.duringunbundle2 = True
        raise