]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Split/Split.py
BaseTools: Convert Split tool to python
[mirror_edk2.git] / BaseTools / Source / Python / Split / Split.py
CommitLineData
5b4a97bb
BF
1# @file\r
2# Split a file into two pieces at the request offset.\r
3#\r
4# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
5#\r
6# SPDX-License-Identifier: BSD-2-Clause-Patent\r
7#\r
8##\r
9\r
10# Import Modules\r
11#\r
12import argparse\r
13import os\r
14import io\r
15import shutil\r
16import logging\r
17import sys\r
18import tempfile\r
19\r
20parser = argparse.ArgumentParser(description='''\r
21SplitFile creates two Binary files either in the same directory as the current working directory or in the specified directory.\r
22''')\r
23parser.add_argument("-f", "--filename", dest="inputfile",\r
24 required=True, help="The input file to split tool.")\r
25parser.add_argument("-s", "--split", dest="position",\r
26 required=True, help="The number of bytes in the first file. The valid format are HEX, Decimal and Decimal[KMG].")\r
27parser.add_argument("-p", "--prefix", dest="output",\r
28 help="The output folder.")\r
29parser.add_argument("-o", "--firstfile", help="The first file name")\r
30parser.add_argument("-t", "--secondfile", help="The second file name")\r
31parser.add_argument("--version", action="version", version='%(prog)s Version 2.0',\r
32 help="Print debug information.")\r
33\r
34group = parser.add_mutually_exclusive_group()\r
35group.add_argument("-v", "--verbose", action="store_true",\r
36 help="Print debug information.")\r
37group.add_argument("-q", "--quiet", action="store_true",\r
38 help="Disable all messages except fatal errors")\r
39\r
40SizeDict = {\r
41 "K": 1024,\r
42 "M": 1024*1024,\r
43 "G": 1024*1024*1024\r
44}\r
45\r
46\r
47def GetPositionValue(position):\r
48 '''\r
49 Parse the string of the argument position and return a decimal number.\r
50 The valid position formats are\r
51 1. HEX\r
52 e.g. 0x1000 or 0X1000\r
53 2. Decimal\r
54 e.g. 100\r
55 3. Decimal[KMG]\r
56 e.g. 100K or 100M or 100G or 100k or 100m or 100g\r
57 '''\r
58 logger = logging.getLogger('Split')\r
59 PosVal = 0\r
60 header = position[:2].upper()\r
61 tailer = position[-1].upper()\r
62\r
63 try:\r
64 if tailer in SizeDict:\r
65 PosVal = int(position[:-1]) * SizeDict[tailer]\r
66 else:\r
67 if header == "0X":\r
68 PosVal = int(position, 16)\r
69 else:\r
70 PosVal = int(position)\r
71 except Exception as e:\r
72 logger.error(\r
73 "The parameter %s format is incorrect. The valid format is HEX, Decimal and Decimal[KMG]." % position)\r
74 raise(e)\r
75\r
76 return PosVal\r
77\r
78\r
79def getFileSize(filename):\r
80 '''\r
81 Read the input file and return the file size.\r
82 '''\r
83 logger = logging.getLogger('Split')\r
84 length = 0\r
85 try:\r
86 with open(filename, "rb") as fin:\r
87 fin.seek(0, io.SEEK_END)\r
88 length = fin.tell()\r
89 except Exception as e:\r
90 logger.error("Access file failed: %s", filename)\r
91 raise(e)\r
92\r
93 return length\r
94\r
95\r
96def splitFile(inputfile, position, outputdir=None, outputfile1=None, outputfile2=None):\r
97 '''\r
98 Split the inputfile into outputfile1 and outputfile2 from the position.\r
99 '''\r
100 logger = logging.getLogger('Split')\r
101\r
102 inputfile = os.path.abspath(inputfile)\r
103 workspace = os.path.dirname(inputfile)\r
104 if not os.path.exists(inputfile):\r
105 logger.error("File Not Found: %s" % inputfile)\r
106 raise(Exception)\r
107\r
108 if outputfile1 and outputfile2 and outputfile1 == outputfile2:\r
109 logger.error(\r
110 "The firstfile and the secondfile can't be the same: %s" % outputfile1)\r
111 raise(Exception)\r
112\r
113 if not outputdir:\r
114 outputdir = workspace\r
115 elif not os.path.isabs(outputdir):\r
116 outputdir = os.path.join(workspace, outputdir)\r
117\r
118 # Create dir for the output files\r
119 try:\r
120 if not outputfile1:\r
121 outputfile1 = os.path.abspath(os.path.join(\r
122 outputdir, "{}1".format(os.path.basename(inputfile))))\r
123 else:\r
124 outputfile1 = os.path.abspath(os.path.join(outputdir, outputfile1))\r
125 outputdir = os.path.dirname(outputfile1)\r
126 if not os.path.exists(outputdir):\r
127 os.makedirs(outputdir)\r
128\r
129 if not outputfile2:\r
130 outputfile2 = os.path.abspath(os.path.join(\r
131 outputdir, "{}2".format(os.path.basename(inputfile))))\r
132 else:\r
133 outputfile2 = os.path.abspath(os.path.join(outputdir, outputfile2))\r
134 outputdir = os.path.dirname(outputfile2)\r
135 if not os.path.exists(outputdir):\r
136 os.makedirs(outputdir)\r
137 except Exception as e:\r
138 logger.error("Can't make dir: %s" % outputdir)\r
139 raise(e)\r
140\r
141 if position <= 0:\r
142 if outputfile2 != inputfile:\r
143 shutil.copy2(inputfile, outputfile2)\r
144 with open(outputfile1, "wb") as fout:\r
145 fout.write(b'')\r
146 else:\r
147 inputfilesize = getFileSize(inputfile)\r
148 if position >= inputfilesize:\r
149 if outputfile1 != inputfile:\r
150 shutil.copy2(inputfile, outputfile1)\r
151 with open(outputfile2, "wb") as fout:\r
152 fout.write(b'')\r
153 else:\r
154 try:\r
155 tempdir = tempfile.mkdtemp()\r
156 tempfile1 = os.path.join(tempdir, "file1.bin")\r
157 tempfile2 = os.path.join(tempdir, "file2.bin")\r
158 with open(inputfile, "rb") as fin:\r
159 content1 = fin.read(position)\r
160 with open(tempfile1, "wb") as fout1:\r
161 fout1.write(content1)\r
162\r
163 content2 = fin.read(inputfilesize - position)\r
164 with open(tempfile2, "wb") as fout2:\r
165 fout2.write(content2)\r
166 shutil.copy2(tempfile1, outputfile1)\r
167 shutil.copy2(tempfile2, outputfile2)\r
168 except Exception as e:\r
169 logger.error("Split file failed")\r
170 raise(e)\r
171 finally:\r
172 if os.path.exists(tempdir):\r
173 shutil.rmtree(tempdir)\r
174\r
175\r
176def main():\r
177 args = parser.parse_args()\r
178 status = 0\r
179\r
180 logger = logging.getLogger('Split')\r
181 if args.quiet:\r
182 logger.setLevel(logging.CRITICAL)\r
183 if args.verbose:\r
184 logger.setLevel(logging.DEBUG)\r
185\r
186 lh = logging.StreamHandler(sys.stdout)\r
187 lf = logging.Formatter("%(levelname)-8s: %(message)s")\r
188 lh.setFormatter(lf)\r
189 logger.addHandler(lh)\r
190\r
191 try:\r
192 position = GetPositionValue(args.position)\r
193 splitFile(args.inputfile, position, args.output,\r
194 args.firstfile, args.secondfile)\r
195 except Exception as e:\r
196 status = 1\r
197\r
198 return status\r
199\r
200\r
201if __name__ == "__main__":\r
202 exit(main())\r