Add bitwise_or.py.
This commit is contained in:
parent
2ec1f7c7ff
commit
eb39dcf005
1 changed files with 76 additions and 0 deletions
76
bitwise_or.py
Normal file
76
bitwise_or.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
'''
|
||||
bitwise_or
|
||||
==========
|
||||
|
||||
Merge two or more files by performing bitwise or on their bits.
|
||||
|
||||
> bitwise_or file1 file2 --output file3
|
||||
'''
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from voussoirkit import betterhelp
|
||||
from voussoirkit import interactive
|
||||
from voussoirkit import operatornotify
|
||||
from voussoirkit import pathclass
|
||||
from voussoirkit import pipeable
|
||||
from voussoirkit import vlogging
|
||||
from voussoirkit import winglob
|
||||
|
||||
log = vlogging.getLogger(__name__, 'bitwise_or')
|
||||
|
||||
CHUNK_SIZE = 2**20
|
||||
|
||||
def bitwise_or_argparse(args):
|
||||
patterns = pipeable.input_many(args.files, skip_blank=True, strip=True)
|
||||
files = [file for pattern in patterns for file in winglob.glob(pattern)]
|
||||
files = [pathclass.Path(file) for file in files]
|
||||
|
||||
if len(files) < 2:
|
||||
log.fatal('Need at least two input files.')
|
||||
return 1
|
||||
|
||||
handles = [file.open('rb') for file in files]
|
||||
|
||||
output = pathclass.Path(args.output)
|
||||
if output.is_dir:
|
||||
log.fatal('Output path "%s" is a directory.', args.output)
|
||||
return 1
|
||||
|
||||
if not output.exists:
|
||||
pass
|
||||
elif args.overwrite:
|
||||
pass
|
||||
elif not interactive.getpermission(f'Overwrite "{output.absolute_path}"?'):
|
||||
return 1
|
||||
|
||||
output_handle = output.open('wb')
|
||||
while True:
|
||||
chunk = 0
|
||||
length = 1
|
||||
for handle in handles[:]:
|
||||
read = handle.read(CHUNK_SIZE)
|
||||
length = max(length, len(read))
|
||||
if not read:
|
||||
handles.remove(handle)
|
||||
chunk |= int.from_bytes(read, 'big')
|
||||
if not handles:
|
||||
break
|
||||
output_handle.write(chunk.to_bytes(length, 'big'))
|
||||
pipeable.stdout(output.absolute_path)
|
||||
|
||||
def main(argv):
|
||||
argv = vlogging.set_level_by_argv(log, argv)
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
|
||||
parser.add_argument('files', nargs='+')
|
||||
parser.add_argument('--output', required=True)
|
||||
parser.add_argument('--overwrite', action='store_true')
|
||||
parser.set_defaults(func=bitwise_or_argparse)
|
||||
|
||||
return betterhelp.single_main(argv, parser, __doc__)
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main(sys.argv[1:]))
|
Loading…
Reference in a new issue