Ejemplo n.º 1
0
 def write_pack(cls, object_iter, pack_write, index_write=None, 
                 object_count = None, zlib_compression = zlib.Z_BEST_SPEED):
     """
     Create a new pack by putting all objects obtained by the object_iterator
     into a pack which is written using the pack_write method.
     The respective index is produced as well if index_write is not Non.
     
     :param object_iter: iterator yielding odb output objects
     :param pack_write: function to receive strings to write into the pack stream
     :param indx_write: if not None, the function writes the index file corresponding
         to the pack.
     :param object_count: if you can provide the amount of objects in your iteration, 
         this would be the place to put it. Otherwise we have to pre-iterate and store 
         all items into a list to get the number, which uses more memory than necessary.
     :param zlib_compression: the zlib compression level to use
     :return: tuple(pack_sha, index_binsha) binary sha over all the contents of the pack
         and over all contents of the index. If index_write was None, index_binsha will be None
     :note: The destination of the write functions is up to the user. It could
         be a socket, or a file for instance
     :note: writes only undeltified objects"""
     objs = object_iter
     if not object_count:
         if not isinstance(object_iter, (tuple, list)):
             objs = list(object_iter)
         #END handle list type
         object_count = len(objs)
     #END handle object
     
     pack_writer = FlexibleSha1Writer(pack_write)
     pwrite = pack_writer.write
     ofs = 0                                         # current offset into the pack file
     index = None
     wants_index = index_write is not None
     
     # write header
     pwrite(pack('>LLL', PackFile.pack_signature, PackFile.pack_version_default, object_count))
     ofs += 12
     
     if wants_index:
         index = IndexWriter()
     #END handle index header
     
     actual_count = 0
     for obj in objs:
         actual_count += 1
         crc = 0
         
         # object header
         hdr = create_pack_object_header(obj.type_id, obj.size)
         if index_write:
             crc = crc32(hdr)
         else:
             crc = None
         #END handle crc
         pwrite(hdr)
         
         # data stream
         zstream = zlib.compressobj(zlib_compression)
         ostream = obj.stream
         br, bw, crc = write_stream_to_pack(ostream.read, pwrite, zstream, base_crc = crc)
         assert(br == obj.size)
         if wants_index:
             index.append(obj.binsha, crc, ofs)
         #END handle index
         
         ofs += len(hdr) + bw
         if actual_count == object_count:
             break
         #END abort once we are done
     #END for each object
     
     if actual_count != object_count:
         raise ValueError("Expected to write %i objects into pack, but received only %i from iterators" % (object_count, actual_count))
     #END count assertion
     
     # write footer
     pack_sha = pack_writer.sha(as_hex = False)
     assert len(pack_sha) == 20
     pack_write(pack_sha)
     ofs += len(pack_sha)                            # just for completeness ;)
     
     index_sha = None
     if wants_index:
         index_sha = index.write(pack_sha, index_write)
     #END handle index
     
     return pack_sha, index_sha
Ejemplo n.º 2
0
    def write_pack(cls,
                   object_iter,
                   pack_write,
                   index_write=None,
                   object_count=None,
                   zlib_compression=zlib.Z_BEST_SPEED):
        """
		Create a new pack by putting all objects obtained by the object_iterator
		into a pack which is written using the pack_write method.
		The respective index is produced as well if index_write is not Non.
		
		:param object_iter: iterator yielding odb output objects
		:param pack_write: function to receive strings to write into the pack stream
		:param indx_write: if not None, the function writes the index file corresponding
			to the pack.
		:param object_count: if you can provide the amount of objects in your iteration, 
			this would be the place to put it. Otherwise we have to pre-iterate and store 
			all items into a list to get the number, which uses more memory than necessary.
		:param zlib_compression: the zlib compression level to use
		:return: tuple(pack_sha, index_binsha) binary sha over all the contents of the pack
			and over all contents of the index. If index_write was None, index_binsha will be None
		:note: The destination of the write functions is up to the user. It could
			be a socket, or a file for instance
		:note: writes only undeltified objects"""
        objs = object_iter
        if not object_count:
            if not isinstance(object_iter, (tuple, list)):
                objs = list(object_iter)
            #END handle list type
            object_count = len(objs)
        #END handle object

        pack_writer = FlexibleSha1Writer(pack_write)
        pwrite = pack_writer.write
        ofs = 0  # current offset into the pack file
        index = None
        wants_index = index_write is not None

        # write header
        pwrite(
            pack('>LLL', PackFile.pack_signature,
                 PackFile.pack_version_default, object_count))
        ofs += 12

        if wants_index:
            index = IndexWriter()
        #END handle index header

        actual_count = 0
        for obj in objs:
            actual_count += 1
            crc = 0

            # object header
            hdr = create_pack_object_header(obj.type_id, obj.size)
            if index_write:
                crc = crc32(hdr)
            else:
                crc = None
            #END handle crc
            pwrite(hdr)

            # data stream
            zstream = zlib.compressobj(zlib_compression)
            ostream = obj.stream
            br, bw, crc = write_stream_to_pack(ostream.read,
                                               pwrite,
                                               zstream,
                                               base_crc=crc)
            assert (br == obj.size)
            if wants_index:
                index.append(obj.binsha, crc, ofs)
            #END handle index

            ofs += len(hdr) + bw
            if actual_count == object_count:
                break
            #END abort once we are done
        #END for each object

        if actual_count != object_count:
            raise ValueError(
                "Expected to write %i objects into pack, but received only %i from iterators"
                % (object_count, actual_count))
        #END count assertion

        # write footer
        pack_sha = pack_writer.sha(as_hex=False)
        assert len(pack_sha) == 20
        pack_write(pack_sha)
        ofs += len(pack_sha)  # just for completeness ;)

        index_sha = None
        if wants_index:
            index_sha = index.write(pack_sha, index_write)
        #END handle index

        return pack_sha, index_sha