Add bitwise_or.py.

This commit is contained in:
voussoir 2021-05-14 17:53:04 -07:00
parent 2ec1f7c7ff
commit eb39dcf005
No known key found for this signature in database
GPG key ID: 5F7554F8C26DACCB

76
bitwise_or.py Normal file
View 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:]))