| # @file | |
| # Split a file into two pieces at the request offset. | |
| # | |
| # Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> | |
| # | |
| # SPDX-License-Identifier: BSD-2-Clause-Patent | |
| # | |
| ## | |
| # Import Modules | |
| # | |
| import argparse | |
| import os | |
| import io | |
| import shutil | |
| import logging | |
| import sys | |
| import tempfile | |
| parser = argparse.ArgumentParser(description=''' | |
| SplitFile creates two Binary files either in the same directory as the current working directory or in the specified directory. | |
| ''') | |
| parser.add_argument("-f", "--filename", dest="inputfile", | |
| required=True, help="The input file to split tool.") | |
| parser.add_argument("-s", "--split", dest="position", | |
| required=True, help="The number of bytes in the first file. The valid format are HEX, Decimal and Decimal[KMG].") | |
| parser.add_argument("-p", "--prefix", dest="output", | |
| help="The output folder.") | |
| parser.add_argument("-o", "--firstfile", help="The first file name") | |
| parser.add_argument("-t", "--secondfile", help="The second file name") | |
| parser.add_argument("--version", action="version", version='%(prog)s Version 2.0', | |
| help="Print debug information.") | |
| group = parser.add_mutually_exclusive_group() | |
| group.add_argument("-v", "--verbose", action="store_true", | |
| help="Print debug information.") | |
| group.add_argument("-q", "--quiet", action="store_true", | |
| help="Disable all messages except fatal errors") | |
| SizeDict = { | |
| "K": 1024, | |
| "M": 1024*1024, | |
| "G": 1024*1024*1024 | |
| } | |
| def GetPositionValue(position): | |
| ''' | |
| Parse the string of the argument position and return a decimal number. | |
| The valid position formats are | |
| 1. HEX | |
| e.g. 0x1000 or 0X1000 | |
| 2. Decimal | |
| e.g. 100 | |
| 3. Decimal[KMG] | |
| e.g. 100K or 100M or 100G or 100k or 100m or 100g | |
| ''' | |
| logger = logging.getLogger('Split') | |
| PosVal = 0 | |
| header = position[:2].upper() | |
| tailer = position[-1].upper() | |
| try: | |
| if tailer in SizeDict: | |
| PosVal = int(position[:-1]) * SizeDict[tailer] | |
| else: | |
| if header == "0X": | |
| PosVal = int(position, 16) | |
| else: | |
| PosVal = int(position) | |
| except Exception as e: | |
| logger.error( | |
| "The parameter %s format is incorrect. The valid format is HEX, Decimal and Decimal[KMG]." % position) | |
| raise(e) | |
| return PosVal | |
| def getFileSize(filename): | |
| ''' | |
| Read the input file and return the file size. | |
| ''' | |
| logger = logging.getLogger('Split') | |
| length = 0 | |
| try: | |
| with open(filename, "rb") as fin: | |
| fin.seek(0, io.SEEK_END) | |
| length = fin.tell() | |
| except Exception as e: | |
| logger.error("Access file failed: %s", filename) | |
| raise(e) | |
| return length | |
| def getoutputfileabs(inputfile, prefix, outputfile,index): | |
| inputfile = os.path.abspath(inputfile) | |
| if outputfile is None: | |
| if prefix is None: | |
| outputfileabs = os.path.join(os.path.dirname(inputfile), "{}{}".format(os.path.basename(inputfile),index)) | |
| else: | |
| if os.path.isabs(prefix): | |
| outputfileabs = os.path.join(prefix, "{}{}".format(os.path.basename(inputfile),index)) | |
| else: | |
| outputfileabs = os.path.join(os.getcwd(), prefix, "{}{}".format(os.path.basename(inputfile),index)) | |
| elif not os.path.isabs(outputfile): | |
| if prefix is None: | |
| outputfileabs = os.path.join(os.getcwd(), outputfile) | |
| else: | |
| if os.path.isabs(prefix): | |
| outputfileabs = os.path.join(prefix, outputfile) | |
| else: | |
| outputfileabs = os.path.join(os.getcwd(), prefix, outputfile) | |
| else: | |
| outputfileabs = outputfile | |
| return outputfileabs | |
| def splitFile(inputfile, position, outputdir=None, outputfile1=None, outputfile2=None): | |
| ''' | |
| Split the inputfile into outputfile1 and outputfile2 from the position. | |
| ''' | |
| logger = logging.getLogger('Split') | |
| if not os.path.exists(inputfile): | |
| logger.error("File Not Found: %s" % inputfile) | |
| raise(Exception) | |
| if outputfile1 and outputfile2 and outputfile1 == outputfile2: | |
| logger.error( | |
| "The firstfile and the secondfile can't be the same: %s" % outputfile1) | |
| raise(Exception) | |
| # Create dir for the output files | |
| try: | |
| outputfile1 = getoutputfileabs(inputfile, outputdir, outputfile1,1) | |
| outputfolder = os.path.dirname(outputfile1) | |
| if not os.path.exists(outputfolder): | |
| os.makedirs(outputfolder) | |
| outputfile2 = getoutputfileabs(inputfile, outputdir, outputfile2,2) | |
| outputfolder = os.path.dirname(outputfile2) | |
| if not os.path.exists(outputfolder): | |
| os.makedirs(outputfolder) | |
| except Exception as e: | |
| logger.error("Can't make dir: %s" % outputfolder) | |
| raise(e) | |
| if position <= 0: | |
| if outputfile2 != os.path.abspath(inputfile): | |
| shutil.copyfile(os.path.abspath(inputfile), outputfile2) | |
| with open(outputfile1, "wb") as fout: | |
| fout.write(b'') | |
| else: | |
| inputfilesize = getFileSize(inputfile) | |
| if position >= inputfilesize: | |
| if outputfile1 != os.path.abspath(inputfile): | |
| shutil.copyfile(os.path.abspath(inputfile), outputfile1) | |
| with open(outputfile2, "wb") as fout: | |
| fout.write(b'') | |
| else: | |
| try: | |
| tempdir = tempfile.mkdtemp() | |
| tempfile1 = os.path.join(tempdir, "file1.bin") | |
| tempfile2 = os.path.join(tempdir, "file2.bin") | |
| with open(inputfile, "rb") as fin: | |
| content1 = fin.read(position) | |
| with open(tempfile1, "wb") as fout1: | |
| fout1.write(content1) | |
| content2 = fin.read(inputfilesize - position) | |
| with open(tempfile2, "wb") as fout2: | |
| fout2.write(content2) | |
| shutil.copyfile(tempfile1, outputfile1) | |
| shutil.copyfile(tempfile2, outputfile2) | |
| except Exception as e: | |
| logger.error("Split file failed") | |
| raise(e) | |
| finally: | |
| if os.path.exists(tempdir): | |
| shutil.rmtree(tempdir) | |
| def main(): | |
| args = parser.parse_args() | |
| status = 0 | |
| logger = logging.getLogger('Split') | |
| if args.quiet: | |
| logger.setLevel(logging.CRITICAL) | |
| if args.verbose: | |
| logger.setLevel(logging.DEBUG) | |
| lh = logging.StreamHandler(sys.stdout) | |
| lf = logging.Formatter("%(levelname)-8s: %(message)s") | |
| lh.setFormatter(lf) | |
| logger.addHandler(lh) | |
| try: | |
| position = GetPositionValue(args.position) | |
| splitFile(args.inputfile, position, args.output, | |
| args.firstfile, args.secondfile) | |
| except Exception as e: | |
| status = 1 | |
| return status | |
| if __name__ == "__main__": | |
| exit(main()) |