]>
Commit | Line | Data |
---|---|---|
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 | |
12 | import argparse\r | |
13 | import os\r | |
14 | import io\r | |
15 | import shutil\r | |
16 | import logging\r | |
17 | import sys\r | |
18 | import tempfile\r | |
19 | \r | |
20 | parser = argparse.ArgumentParser(description='''\r | |
21 | SplitFile creates two Binary files either in the same directory as the current working directory or in the specified directory.\r | |
22 | ''')\r | |
23 | parser.add_argument("-f", "--filename", dest="inputfile",\r | |
24 | required=True, help="The input file to split tool.")\r | |
25 | parser.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 | |
27 | parser.add_argument("-p", "--prefix", dest="output",\r | |
28 | help="The output folder.")\r | |
29 | parser.add_argument("-o", "--firstfile", help="The first file name")\r | |
30 | parser.add_argument("-t", "--secondfile", help="The second file name")\r | |
31 | parser.add_argument("--version", action="version", version='%(prog)s Version 2.0',\r | |
32 | help="Print debug information.")\r | |
33 | \r | |
34 | group = parser.add_mutually_exclusive_group()\r | |
35 | group.add_argument("-v", "--verbose", action="store_true",\r | |
36 | help="Print debug information.")\r | |
37 | group.add_argument("-q", "--quiet", action="store_true",\r | |
38 | help="Disable all messages except fatal errors")\r | |
39 | \r | |
40 | SizeDict = {\r | |
41 | "K": 1024,\r | |
42 | "M": 1024*1024,\r | |
43 | "G": 1024*1024*1024\r | |
44 | }\r | |
45 | \r | |
46 | \r | |
47 | def 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 | |
79 | def 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 |
95 | def 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 |
117 | def 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 BF |
150 | if outputfile2 != os.path.abspath(inputfile):\r |
151 | shutil.copy2(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 BF |
157 | if outputfile1 != os.path.abspath(inputfile):\r |
158 | shutil.copy2(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 | |
174 | shutil.copy2(tempfile1, outputfile1)\r | |
175 | shutil.copy2(tempfile2, outputfile2)\r | |
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 | |
184 | def 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 | |
209 | if __name__ == "__main__":\r | |
210 | exit(main())\r |