示例#1
0
文件: rar.py 项目: vadmium/rerar
def write_block(file, type, flags, data):
    block = bytearray()
    for part in data: block.extend(part)
    
    header = S_BLK_HDR_DATA.pack(type, flags, S_BLK_HDR.size + len(block))
    
    crc = crc32(header)
    crc = crc32(block, crc)
    file.write(S_SHORT.pack(crc & bitmask(16)))
    
    file.write(header)
    file.write(block)
示例#2
0
def write_block(file, btype, flags, data):
    block = bytearray()
    for part in data:
        block.extend(part)

    header = S_BLK_HDR_DATA.pack(btype, flags, S_BLK_HDR.size + len(block))

    crc = crc32(header)
    crc = crc32(block, crc)
    file.write(S_SHORT.pack(crc & bitmask(16)))

    file.write(header)
    file.write(block)
示例#3
0
def write_file(volume,
               file,
               split_before,
               split_after,
               name,
               is_unicode,
               dictsize,
               host_os,
               attr,
               accum_crc,
               dostime,
               xtime=None,
               size=None,
               pack_size=None):
    size_64 = size_64_encode(pack_size, size)
    header_size = file_hdr_size(name, xtime, size_64)
    volume.seek(+header_size, io.SEEK_CUR)

    left = pack_size
    crc = 0 if split_after else accum_crc
    while left > 0:
        chunk = file.read(min(FILE_COPY_CRC_BUF, left))
        left -= len(chunk)
        volume.write(chunk)
        crc = crc32(chunk, crc)
        if split_after:
            accum_crc = crc32(chunk, accum_crc)

    parts = list()
    flags = (RAR_LONG_BLOCK ^ split_before * RAR_FILE_SPLIT_BEFORE
             ^ split_after * RAR_FILE_SPLIT_AFTER ^ dictsize
             ^ is_unicode * RAR_FILE_UNICODE)
    parts.append(
        S_FILE_HDR.pack(pack_size & bitmask(32), size & bitmask(32), host_os,
                        crc, dostime, 20, ord("0"), len(name), attr))

    if size_64 is not None:
        flags ^= RAR_FILE_LARGE
        parts.append(size_64)

    parts.append(name)

    if xtime is not None:
        flags ^= RAR_FILE_EXTTIME
        parts.append(xtime)

    volume.seek(-pack_size - header_size, io.SEEK_CUR)
    write_block(volume, RAR_BLOCK_FILE, flags, parts)
    volume.seek(+pack_size, io.SEEK_CUR)

    if split_after: return accum_crc
示例#4
0
文件: rar.py 项目: vadmium/rerar
def file_crc32(file, size):
    crc = 0
    while size > 0:
        chunk = file.read(min(FILE_CRC_BUF, size))
        size -= len(chunk)
        crc = crc32(chunk, crc)
    return crc
示例#5
0
def file_crc32(file, size):
    crc = 0
    while size > 0:
        chunk = file.read(min(FILE_CRC_BUF, size))
        size -= len(chunk)
        crc = crc32(chunk, crc)
    return crc
示例#6
0
文件: rar.py 项目: vadmium/rerar
def write_file(volume, file, split_before, split_after, name, is_unicode,
dict, host_os, attr, accum_crc, dostime, xtime=None, size=None,
pack_size=None):
    size_64 = size_64_encode(pack_size, size)
    header_size = file_hdr_size(name, xtime, size_64)
    volume.seek(+header_size, io.SEEK_CUR)
    
    left = pack_size
    crc = 0 if split_after else accum_crc
    while left > 0:
        chunk = file.read(min(FILE_COPY_CRC_BUF, left))
        left -= len(chunk)
        volume.write(chunk)
        crc = crc32(chunk, crc)
        if split_after:
            accum_crc = crc32(chunk, accum_crc)
    
    parts = list()
    flags = (RAR_LONG_BLOCK ^ split_before * RAR_FILE_SPLIT_BEFORE ^
        split_after * RAR_FILE_SPLIT_AFTER ^ dict ^
        is_unicode * RAR_FILE_UNICODE)
    parts.append(S_FILE_HDR.pack(
        pack_size & bitmask(32), size & bitmask(32),
        host_os, crc, dostime, 20, ord("0"), len(name), attr
    ))
    
    if size_64 is not None:
        flags ^= RAR_FILE_LARGE
        parts.append(size_64)
    
    parts.append(name)
    
    if xtime is not None:
        flags ^= RAR_FILE_EXTTIME
        parts.append(xtime)
    
    volume.seek(-pack_size - header_size, io.SEEK_CUR)
    write_block(volume, RAR_BLOCK_FILE, flags, parts)
    volume.seek(+pack_size, io.SEEK_CUR)
    
    if split_after: return accum_crc
示例#7
0
文件: rar.py 项目: vadmium/rerar
def write_rr(version, host_os, volume, rr_count):
    prot_size = volume.tell()
    (rr_crcs, rr_sects) = rr_calc(volume, rr_count, prot_size)
    
    crc = crc32(rr_crcs, RR_CRC_INIT)
    for s in rr_sects:
        crc = crc32(s.buffer(), crc)
    
    prot_sect_count = len(rr_crcs) // S_SHORT.size
    size = prot_sect_count * RR_CRC_SIZE + rr_count * RR_SECT_SIZE
    
    if version < 3:
        write_block(volume,
            type=RAR_BLOCK_OLD_RECOVERY,
            flags=RAR_LONG_BLOCK ^ RAR_SKIP_IF_UNKNOWN,
            data=(
                S_LONG.pack(size),
                (20,),
                S_SHORT.pack(rr_count),
                S_LONG.pack(prot_sect_count),
                RR_PROTECT_2,
            ))
    else:
        write_block(volume,
            type=RAR_BLOCK_SUB,
            flags=RAR_LONG_BLOCK ^ RAR_SKIP_IF_UNKNOWN,
            data=(
                S_FILE_HDR.pack(size, size, host_os, crc, 0, 29, ord("0"),
                    len(RR_SUB_NAME), 0),
                RR_SUB_NAME,
                RR_PROTECT_3,
                S_LONG.pack(rr_count),
                struct.pack("<Q", prot_sect_count),
            ))
    
    volume.write(rr_crcs)
    for s in rr_sects:
        volume.write(s.buffer())
示例#8
0
def write_rr(version, host_os, volume, rr_count):
    prot_size = volume.tell()
    (rr_crcs, rr_sects) = rr_calc(volume, rr_count, prot_size)

    crc = crc32(rr_crcs, RR_CRC_INIT)
    for s in rr_sects:
        crc = crc32(s.buffer(), crc)

    prot_sect_count = len(rr_crcs) // S_SHORT.size
    size = prot_sect_count * RR_CRC_SIZE + rr_count * RR_SECT_SIZE

    if version < 3:
        write_block(volume,
                    type=RAR_BLOCK_OLD_RECOVERY,
                    flags=RAR_LONG_BLOCK ^ RAR_SKIP_IF_UNKNOWN,
                    data=(
                        S_LONG.pack(size),
                        (20, ),
                        S_SHORT.pack(rr_count),
                        S_LONG.pack(prot_sect_count),
                        RR_PROTECT_2,
                    ))
    else:
        write_block(volume,
                    type=RAR_BLOCK_SUB,
                    flags=RAR_LONG_BLOCK ^ RAR_SKIP_IF_UNKNOWN,
                    data=(
                        S_FILE_HDR.pack(size, size, host_os, crc, 0, 29,
                                        ord("0"), len(RR_SUB_NAME), 0),
                        RR_SUB_NAME,
                        RR_PROTECT_3,
                        S_LONG.pack(rr_count),
                        struct.pack("<Q", prot_sect_count),
                    ))

    volume.write(rr_crcs)
    for s in rr_sects:
        volume.write(s.buffer())
示例#9
0
文件: rar.py 项目: vadmium/rerar
def rr_calc(volume, rr_count, size):
    volume.seek(0)
    
    rr_crcs = bytearray()
    rr_sects = tuple(BitVector(RR_SECT_SIZE) for i in range(rr_count))
    
    slice = 0
    while size > 0:
        if size < RR_SECT_SIZE:
            chunk = volume.read(size).ljust(RR_SECT_SIZE, bytes((0,)))
            size = 0
        else:
            chunk = volume.read(RR_SECT_SIZE)
            size -= RR_SECT_SIZE
        
        rr_crcs.extend(S_SHORT.pack(~crc32(chunk) & bitmask(16)))
        rr_sects[slice].xor(chunk)
        slice = (slice + 1) % rr_count
    
    return (rr_crcs, rr_sects)
示例#10
0
def rr_calc(volume, rr_count, size):
    volume.seek(0)

    rr_crcs = bytearray()
    rr_sects = tuple(BitVector(RR_SECT_SIZE) for _ in range(rr_count))

    aslice = 0
    while size > 0:
        if size < RR_SECT_SIZE:
            chunk = volume.read(size).ljust(RR_SECT_SIZE, bytes((0, )))
            size = 0
        else:
            chunk = volume.read(RR_SECT_SIZE)
            size -= RR_SECT_SIZE

        rr_crcs.extend(S_SHORT.pack(~crc32(chunk) & bitmask(16)))
        rr_sects[aslice].xor(chunk)
        aslice = (aslice + 1) % rr_count

    return (rr_crcs, rr_sects)