]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Split/Split.py
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
43a11338
BF
95def getoutputfileabs(inputfile, prefix, outputfile,index):\r
96 inputfile = os.path.abspath(inputfile)\r
97 if outputfile is None:\r
98 if prefix is None:\r
99 outputfileabs = os.path.join(os.path.dirname(inputfile), "{}{}".format(os.path.basename(inputfile),index))\r
100 else:\r
101 if os.path.isabs(prefix):\r
102 outputfileabs = os.path.join(prefix, "{}{}".format(os.path.basename(inputfile),index))\r
103 else:\r
104 outputfileabs = os.path.join(os.getcwd(), prefix, "{}{}".format(os.path.basename(inputfile),index))\r
105 elif not os.path.isabs(outputfile):\r
106 if prefix is None:\r
107 outputfileabs = os.path.join(os.getcwd(), outputfile)\r
108 else:\r
109 if os.path.isabs(prefix):\r
110 outputfileabs = os.path.join(prefix, outputfile)\r
111 else:\r
112 outputfileabs = os.path.join(os.getcwd(), prefix, outputfile)\r
113 else:\r
114 outputfileabs = outputfile\r
115 return outputfileabs\r
5b4a97bb
BF
116\r
117def splitFile(inputfile, position, outputdir=None, outputfile1=None, outputfile2=None):\r
118 '''\r
119 Split the inputfile into outputfile1 and outputfile2 from the position.\r
120 '''\r
121 logger = logging.getLogger('Split')\r
122\r
5b4a97bb
BF
123 if not os.path.exists(inputfile):\r
124 logger.error("File Not Found: %s" % inputfile)\r
125 raise(Exception)\r
126\r
127 if outputfile1 and outputfile2 and outputfile1 == outputfile2:\r
128 logger.error(\r
129 "The firstfile and the secondfile can't be the same: %s" % outputfile1)\r
130 raise(Exception)\r
131\r
5b4a97bb
BF
132 # Create dir for the output files\r
133 try:\r
43a11338
BF
134\r
135 outputfile1 = getoutputfileabs(inputfile, outputdir, outputfile1,1)\r
136 outputfolder = os.path.dirname(outputfile1)\r
137 if not os.path.exists(outputfolder):\r
138 os.makedirs(outputfolder)\r
139\r
140 outputfile2 = getoutputfileabs(inputfile, outputdir, outputfile2,2)\r
141 outputfolder = os.path.dirname(outputfile2)\r
142 if not os.path.exists(outputfolder):\r
143 os.makedirs(outputfolder)\r
144\r
5b4a97bb 145 except Exception as e:\r
43a11338 146 logger.error("Can't make dir: %s" % outputfolder)\r
5b4a97bb
BF
147 raise(e)\r
148\r
149 if position <= 0:\r
43a11338 150 if outputfile2 != os.path.abspath(inputfile):\r
03e77558 151 shutil.copyfile(os.path.abspath(inputfile), outputfile2)\r
5b4a97bb
BF
152 with open(outputfile1, "wb") as fout:\r
153 fout.write(b'')\r
154 else:\r
155 inputfilesize = getFileSize(inputfile)\r
156 if position >= inputfilesize:\r
43a11338 157 if outputfile1 != os.path.abspath(inputfile):\r
03e77558 158 shutil.copyfile(os.path.abspath(inputfile), outputfile1)\r
5b4a97bb
BF
159 with open(outputfile2, "wb") as fout:\r
160 fout.write(b'')\r
161 else:\r
162 try:\r
163 tempdir = tempfile.mkdtemp()\r
164 tempfile1 = os.path.join(tempdir, "file1.bin")\r
165 tempfile2 = os.path.join(tempdir, "file2.bin")\r
166 with open(inputfile, "rb") as fin:\r
167 content1 = fin.read(position)\r
168 with open(tempfile1, "wb") as fout1:\r
169 fout1.write(content1)\r
170\r
171 content2 = fin.read(inputfilesize - position)\r
172 with open(tempfile2, "wb") as fout2:\r
173 fout2.write(content2)\r
03e77558
BF
174 shutil.copyfile(tempfile1, outputfile1)\r
175 shutil.copyfile(tempfile2, outputfile2)\r
5b4a97bb
BF
176 except Exception as e:\r
177 logger.error("Split file failed")\r
178 raise(e)\r
179 finally:\r
180 if os.path.exists(tempdir):\r
181 shutil.rmtree(tempdir)\r
182\r
183\r
184def main():\r
185 args = parser.parse_args()\r
186 status = 0\r
187\r
188 logger = logging.getLogger('Split')\r
189 if args.quiet:\r
190 logger.setLevel(logging.CRITICAL)\r
191 if args.verbose:\r
192 logger.setLevel(logging.DEBUG)\r
193\r
194 lh = logging.StreamHandler(sys.stdout)\r
195 lf = logging.Formatter("%(levelname)-8s: %(message)s")\r
196 lh.setFormatter(lf)\r
197 logger.addHandler(lh)\r
198\r
199 try:\r
200 position = GetPositionValue(args.position)\r
201 splitFile(args.inputfile, position, args.output,\r
202 args.firstfile, args.secondfile)\r
203 except Exception as e:\r
204 status = 1\r
205\r
206 return status\r
207\r
208\r
209if __name__ == "__main__":\r
210 exit(main())\r