Exemple #1
0
def time_encode(tm, frac=0):
    dostime = (
        tm.tm_sec >> 1 << DOS_2SEC_BIT ^
        tm.tm_min << DOS_MIN_BIT ^
        tm.tm_hour << DOS_HOUR_BIT ^
        tm.tm_mday << DOS_DAY_BIT ^
        tm.tm_mon << DOS_MONTH_BIT ^
        tm.tm_year - 1980 << DOS_YEAR_BIT)
    
    one_sec = tm.tm_sec & 1
    if not frac and not one_sec: return (dostime, None)
    
    flags = 1 << TIME_VALID_BIT
    flags |= one_sec << TIME_ONE_BIT
    frac = int(frac * 10 ** TIME_FRAC_DIGITS)
    
    size = TIME_FRAC_BYTES
    while size > 0:
        if frac & 0xFF: break
        frac >>= 8
        size -= 1
    flags |= size << TIME_SIZE_BIT
    
    xtime = bytearray(S_SHORT.pack(
        flags << MTIME_INDEX * TIME_FLAG_BITS))
    
    for i in range(size):
        xtime.append(frac & 0xFF)
        frac >>= 8
    
    return (dostime, xtime)
Exemple #2
0
def time_encode(tm, frac=0):
    dostime = (tm.tm_sec >> 1 << DOS_2SEC_BIT ^ tm.tm_min << DOS_MIN_BIT
               ^ tm.tm_hour << DOS_HOUR_BIT ^ tm.tm_mday << DOS_DAY_BIT
               ^ tm.tm_mon << DOS_MONTH_BIT
               ^ tm.tm_year - 1980 << DOS_YEAR_BIT)

    one_sec = tm.tm_sec & 1
    if not frac and not one_sec: return (dostime, None)

    flags = 1 << TIME_VALID_BIT
    flags |= one_sec << TIME_ONE_BIT
    frac = int(frac * 10**TIME_FRAC_DIGITS)

    size = TIME_FRAC_BYTES
    while size > 0:
        if frac & 0xFF: break
        frac >>= 8
        size -= 1
    flags |= size << TIME_SIZE_BIT

    xtime = bytearray(S_SHORT.pack(flags << MTIME_INDEX * TIME_FLAG_BITS))

    for _ in range(size):
        xtime.append(frac & 0xFF)
        frac >>= 8

    return (dostime, xtime)
Exemple #3
0
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)
Exemple #4
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)
Exemple #5
0
def write_end(volume, version, flags, volnum, is_last_vol):
    size = volume.tell()
    volume.seek(0)
    crc = file_crc32(volume, size)
    
    if version >= 3:
        flags |= (RAR_SKIP_IF_UNKNOWN ^
            (not is_last_vol) * RAR_ENDARC_NEXT_VOLUME)
        parts = list()
        
        if flags & RAR_ENDARC_DATACRC:
            parts.append(S_LONG.pack(crc))
        if flags & RAR_ENDARC_VOLNR:
            parts.append(S_SHORT.pack(volnum))
        if flags & RAR_ENDARC_REVSPACE:
            parts.append(0 for i in range(END_EXTRA))
        
        write_block(volume, RAR_BLOCK_ENDARC, flags, parts)
    
    return crc
Exemple #6
0
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)
Exemple #7
0
def write_end(volume, version, flags, volnum, is_last_vol):
    size = volume.tell()
    volume.seek(0)
    crc = file_crc32(volume, size)

    if version >= 3:
        flags |= (RAR_SKIP_IF_UNKNOWN ^
                  (not is_last_vol) * RAR_ENDARC_NEXT_VOLUME)
        parts = list()

        if flags & RAR_ENDARC_DATACRC:
            parts.append(S_LONG.pack(crc))
        if flags & RAR_ENDARC_VOLNR:
            parts.append(S_SHORT.pack(volnum))
        if flags & RAR_ENDARC_REVSPACE:
            parts.append(0 for _ in range(END_EXTRA))

        write_block(volume, RAR_BLOCK_ENDARC, flags, parts)

    return crc
Exemple #8
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)
Exemple #9
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())
Exemple #10
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())