]>
Commit | Line | Data |
---|---|---|
878ddf1f | 1 | /** @file\r |
2 | GenSectionTask class.\r | |
3 | \r | |
4 | GenSectionTask is to call GenSection.exe to generate Section.\r | |
5 | \r | |
6 | Copyright (c) 2006, Intel Corporation\r | |
7 | All rights reserved. This program and the accompanying materials\r | |
8 | are licensed and made available under the terms and conditions of the BSD License\r | |
9 | which accompanies this distribution. The full text of the license may be found at\r | |
10 | http://opensource.org/licenses/bsd-license.php\r | |
11 | \r | |
12 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
13 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
14 | \r | |
5c4eec41 | 15 | **/\r |
878ddf1f | 16 | \r |
17 | package org.tianocore.framework.tasks;\r | |
18 | \r | |
a1ffb10f | 19 | import java.io.ByteArrayOutputStream;\r |
20 | import java.io.DataOutputStream;\r | |
a1ffb10f | 21 | import java.util.ArrayList;\r |
22 | import java.util.Iterator;\r | |
23 | import java.util.List;\r | |
219e2247 | 24 | \r |
25 | import org.apache.tools.ant.BuildException;\r | |
878ddf1f | 26 | import org.apache.tools.ant.Project;\r |
27 | import org.apache.tools.ant.Task;\r | |
878ddf1f | 28 | import org.apache.tools.ant.taskdefs.Execute;\r |
29 | import org.apache.tools.ant.taskdefs.LogStreamHandler;\r | |
30 | import org.apache.tools.ant.types.Commandline;\r | |
a1ffb10f | 31 | import org.tianocore.common.logger.EdkLog;\r |
878ddf1f | 32 | \r |
5c4eec41 | 33 | public class GenSectionTask extends Task implements EfiDefine, Section,\r |
34 | FfsTypes {\r | |
93f5dd0a | 35 | //\r |
36 | // inputfile name\r | |
37 | //\r | |
38 | private FileArg inputFile = new FileArg();\r | |
5c4eec41 | 39 | \r |
93f5dd0a | 40 | //\r |
41 | // outputfile name\r | |
42 | //\r | |
43 | private FileArg outputFile = new FileArg();\r | |
5c4eec41 | 44 | \r |
93f5dd0a | 45 | //\r |
46 | // section type\r | |
47 | //\r | |
48 | private ToolArg sectionType = new ToolArg();\r | |
5c4eec41 | 49 | \r |
93f5dd0a | 50 | //\r |
51 | // version number\r | |
52 | //\r | |
53 | private ToolArg versionNum = new ToolArg();\r | |
5c4eec41 | 54 | \r |
93f5dd0a | 55 | //\r |
56 | // interface string\r | |
57 | //\r | |
58 | private ToolArg interfaceString = new ToolArg();\r | |
5c4eec41 | 59 | \r |
93f5dd0a | 60 | //\r |
61 | // Section file list\r | |
62 | //\r | |
a1ffb10f | 63 | private List<Section> sectFileList = new ArrayList<Section>();\r |
5c4eec41 | 64 | \r |
65 | //\r | |
66 | // flag indicated the <tool> element\r | |
67 | //\r | |
68 | private boolean haveTool = false;\r | |
69 | \r | |
878ddf1f | 70 | /**\r |
5c4eec41 | 71 | * execute\r |
72 | * \r | |
73 | * GenSectionTaks execute is to assemble tool command line & execute tool\r | |
74 | * command line.\r | |
75 | * \r | |
76 | * @throws BuildException\r | |
77 | */\r | |
878ddf1f | 78 | public void execute() throws BuildException {\r |
79 | String command;\r | |
80 | Project project = this.getOwningTarget().getProject();\r | |
81 | //\r | |
82 | // absolute path of efi tools\r | |
83 | //\r | |
2da8968b | 84 | String path = project.getProperty("env.FRAMEWORK_TOOLS_PATH");\r |
878ddf1f | 85 | if (path == null) {\r |
fad77353 | 86 | command = "GenSection";\r |
878ddf1f | 87 | } else {\r |
fad77353 | 88 | command = path + "/" + "GenSection";\r |
878ddf1f | 89 | }\r |
90 | //\r | |
91 | // argument of tools\r | |
92 | //\r | |
5c4eec41 | 93 | String argument = "" + inputFile + outputFile + sectionType\r |
94 | + versionNum + interfaceString;\r | |
878ddf1f | 95 | //\r |
96 | // return value of gensection execution\r | |
97 | //\r | |
98 | int revl = -1;\r | |
99 | \r | |
100 | try {\r | |
101 | Commandline cmdline = new Commandline();\r | |
102 | cmdline.setExecutable(command);\r | |
103 | cmdline.createArgument().setLine(argument);\r | |
104 | \r | |
105 | LogStreamHandler streamHandler = new LogStreamHandler(this,\r | |
106 | Project.MSG_INFO, Project.MSG_WARN);\r | |
107 | Execute runner = new Execute(streamHandler, null);\r | |
108 | \r | |
109 | runner.setAntRun(project);\r | |
110 | runner.setCommandline(cmdline.getCommandline());\r | |
878ddf1f | 111 | \r |
5c4eec41 | 112 | EdkLog.log(this, inputFile.toFileList() + " => "\r |
113 | + outputFile.toFileList());\r | |
114 | EdkLog.log(this, EdkLog.EDK_VERBOSE, Commandline.toString(cmdline\r | |
115 | .getCommandline()));\r | |
93f5dd0a | 116 | \r |
878ddf1f | 117 | revl = runner.execute();\r |
118 | if (EFI_SUCCESS == revl) {\r | |
93f5dd0a | 119 | EdkLog.log(this, EdkLog.EDK_VERBOSE, "GenSection succeeded!");\r |
878ddf1f | 120 | } else {\r |
121 | //\r | |
122 | // command execution fail\r | |
123 | //\r | |
5c4eec41 | 124 | EdkLog.log(this, EdkLog.EDK_INFO, "ERROR = "\r |
125 | + Integer.toHexString(revl));\r | |
3f7b510e | 126 | throw new BuildException("GenSection failed!");\r |
878ddf1f | 127 | }\r |
128 | } catch (Exception e) {\r | |
129 | throw new BuildException(e.getMessage());\r | |
130 | }\r | |
131 | }\r | |
132 | \r | |
133 | /**\r | |
5c4eec41 | 134 | * getInputFile\r |
135 | * \r | |
136 | * This function is to get class member "inputFile".\r | |
137 | * \r | |
138 | * @return name of input file\r | |
139 | */\r | |
878ddf1f | 140 | public String getInputFile() {\r |
93f5dd0a | 141 | return this.inputFile.getValue();\r |
878ddf1f | 142 | }\r |
143 | \r | |
144 | /**\r | |
5c4eec41 | 145 | * setInputFile\r |
146 | * \r | |
147 | * This function is to set class member "inputFile".\r | |
148 | * \r | |
149 | * @param inputFile\r | |
150 | * name of input file\r | |
151 | */\r | |
878ddf1f | 152 | public void setInputFile(String inputFile) {\r |
93f5dd0a | 153 | this.inputFile.setArg(" -i ", inputFile);\r |
878ddf1f | 154 | }\r |
155 | \r | |
156 | /**\r | |
5c4eec41 | 157 | * getOutputFile\r |
158 | * \r | |
159 | * This function is to get class member "outputFile".\r | |
160 | * \r | |
161 | * @return name of output file\r | |
162 | */\r | |
878ddf1f | 163 | public String getOutputFile() {\r |
93f5dd0a | 164 | return this.outputFile.getValue();\r |
878ddf1f | 165 | }\r |
166 | \r | |
167 | /**\r | |
5c4eec41 | 168 | * setOutputfile\r |
169 | * \r | |
170 | * This function is to set class member "outputFile".\r | |
171 | * \r | |
172 | * @param outputFile\r | |
173 | * name of output file\r | |
174 | */\r | |
878ddf1f | 175 | public void setOutputfile(String outputFile) {\r |
93f5dd0a | 176 | this.outputFile.setArg(" -o ", outputFile);\r |
878ddf1f | 177 | }\r |
178 | \r | |
179 | /**\r | |
5c4eec41 | 180 | * getSectionType\r |
181 | * \r | |
182 | * This function is to get class member "sectionType".\r | |
183 | * \r | |
184 | * @return sectoin type\r | |
185 | */\r | |
878ddf1f | 186 | public String getSectionType() {\r |
93f5dd0a | 187 | return this.sectionType.getValue();\r |
878ddf1f | 188 | }\r |
189 | \r | |
190 | /**\r | |
5c4eec41 | 191 | * setSectionType\r |
192 | * \r | |
193 | * This function is to set class member "sectionType".\r | |
194 | * \r | |
195 | * @param sectionType\r | |
196 | * section type\r | |
197 | */\r | |
878ddf1f | 198 | public void setSectionType(String sectionType) {\r |
93f5dd0a | 199 | this.sectionType.setArg(" -s ", sectionType);\r |
878ddf1f | 200 | }\r |
201 | \r | |
202 | /**\r | |
5c4eec41 | 203 | * getVersionNum\r |
204 | * \r | |
205 | * This function is to get class member "versionNum".\r | |
206 | * \r | |
207 | * @return version number\r | |
208 | */\r | |
878ddf1f | 209 | public String getVersionNum() {\r |
93f5dd0a | 210 | return this.versionNum.getValue();\r |
878ddf1f | 211 | }\r |
212 | \r | |
213 | /**\r | |
5c4eec41 | 214 | * setVersionNume\r |
215 | * \r | |
216 | * This function is to set class member "versionNum".\r | |
217 | * \r | |
218 | * @param versionNum\r | |
219 | * version number\r | |
220 | */\r | |
878ddf1f | 221 | public void setVersionNum(String versionNum) {\r |
93f5dd0a | 222 | this.versionNum.setArg(" -v ", versionNum);\r |
878ddf1f | 223 | }\r |
224 | \r | |
225 | /**\r | |
5c4eec41 | 226 | * getInterfaceString\r |
227 | * \r | |
228 | * This function is to get class member "interfaceString".\r | |
229 | * \r | |
230 | * @return interface string\r | |
231 | */\r | |
878ddf1f | 232 | public String getInterfaceString() {\r |
93f5dd0a | 233 | return this.interfaceString.getValue();\r |
878ddf1f | 234 | }\r |
235 | \r | |
236 | /**\r | |
5c4eec41 | 237 | * setInterfaceString\r |
238 | * \r | |
239 | * This funcion is to set class member "interfaceString".\r | |
240 | * \r | |
241 | * @param interfaceString\r | |
242 | * interface string\r | |
243 | */\r | |
878ddf1f | 244 | public void setInterfaceString(String interfaceString) {\r |
93f5dd0a | 245 | this.interfaceString.setArg(" -a ", "\"" + interfaceString + "\"");\r |
878ddf1f | 246 | }\r |
5c4eec41 | 247 | \r |
a1ffb10f | 248 | /**\r |
5c4eec41 | 249 | * addSectFile\r |
250 | * \r | |
251 | * This function is to add sectFile to list.\r | |
252 | * \r | |
253 | * @param sectFile\r | |
254 | * instance of sectFile.\r | |
255 | */\r | |
256 | public void addSectFile(SectFile sectFile) {\r | |
a1ffb10f | 257 | this.sectFileList.add(sectFile);\r |
258 | }\r | |
259 | \r | |
260 | /**\r | |
5c4eec41 | 261 | * setTool\r |
262 | * \r | |
263 | * This function is to set the class member "Tool";\r | |
264 | * \r | |
265 | * @param tool\r | |
266 | */\r | |
a1ffb10f | 267 | public void addTool(Tool tool) {\r |
268 | this.sectFileList.add(tool);\r | |
5c4eec41 | 269 | this.haveTool = true;\r |
a1ffb10f | 270 | }\r |
5c4eec41 | 271 | \r |
a1ffb10f | 272 | /**\r |
5c4eec41 | 273 | * addGenSection\r |
274 | * \r | |
275 | * This function is to add GenSectin element to list\r | |
276 | * \r | |
277 | * @param task\r | |
278 | * Instance of genSection\r | |
279 | */\r | |
280 | public void addGenSection(GenSectionTask task) {\r | |
a1ffb10f | 281 | this.sectFileList.add(task);\r |
282 | }\r | |
5c4eec41 | 283 | \r |
284 | public void toBuffer(DataOutputStream buffer) {\r | |
a1ffb10f | 285 | //\r |
5c4eec41 | 286 | // Search SectionList find earch section and call it's\r |
287 | // ToBuffer function.\r | |
a1ffb10f | 288 | //\r |
5c4eec41 | 289 | if (this.sectionType.getValue().equalsIgnoreCase(\r |
290 | "EFI_SECTION_COMPRESSION")\r | |
291 | && !this.haveTool) {\r | |
292 | Section sect;\r | |
293 | \r | |
a1ffb10f | 294 | //\r |
5c4eec41 | 295 | // Get section file in compress node.\r |
a1ffb10f | 296 | //\r |
5c4eec41 | 297 | try {\r |
298 | ByteArrayOutputStream bo = new ByteArrayOutputStream();\r | |
299 | DataOutputStream Do = new DataOutputStream(bo);\r | |
300 | \r | |
a1ffb10f | 301 | //\r |
5c4eec41 | 302 | // Get each section which under the compress {};\r |
303 | // And add it is contains to File;\r | |
a1ffb10f | 304 | //\r |
305 | Iterator SectionIter = this.sectFileList.iterator();\r | |
5c4eec41 | 306 | while (SectionIter.hasNext()) {\r |
307 | sect = (Section) SectionIter.next();\r | |
308 | \r | |
a1ffb10f | 309 | //\r |
5c4eec41 | 310 | // Call each section class's toBuffer function.\r |
a1ffb10f | 311 | //\r |
312 | try {\r | |
313 | sect.toBuffer(Do);\r | |
5c4eec41 | 314 | } catch (BuildException e) {\r |
a1ffb10f | 315 | System.out.print(e.getMessage());\r |
5c4eec41 | 316 | throw new BuildException(\r |
317 | "Compress.toBuffer failed at section");\r | |
318 | }\r | |
319 | \r | |
a1ffb10f | 320 | }\r |
5c4eec41 | 321 | Do.close();\r |
322 | \r | |
a1ffb10f | 323 | //\r |
5c4eec41 | 324 | // Call compress\r |
a1ffb10f | 325 | //\r |
326 | byte[] fileBuffer = bo.toByteArray();\r | |
5c4eec41 | 327 | \r |
7dd2b2ad | 328 | synchronized (CompressSection.semaphore) {\r |
5c4eec41 | 329 | Compress myCompress = new Compress(fileBuffer,\r |
330 | fileBuffer.length);\r | |
331 | \r | |
332 | //\r | |
333 | // Add Compress header\r | |
334 | //\r | |
335 | CompressHeader Ch = new CompressHeader();\r | |
336 | Ch.SectionHeader.Size[0] = (byte) ((myCompress.outputBuffer.length + Ch\r | |
337 | .GetSize()) & 0xff);\r | |
338 | Ch.SectionHeader.Size[1] = (byte) (((myCompress.outputBuffer.length + Ch\r | |
339 | .GetSize()) & 0xff00) >> 8);\r | |
340 | Ch.SectionHeader.Size[2] = (byte) (((myCompress.outputBuffer.length + Ch\r | |
341 | .GetSize()) & 0xff0000) >> 16);\r | |
342 | Ch.SectionHeader.type = (byte) EFI_SECTION_COMPRESSION;\r | |
343 | \r | |
344 | //\r | |
345 | // Note: The compressName was not efsfective now. Using the\r | |
346 | // EFI_STANDARD_COMPRSSION for compressType .\r | |
347 | // That is follow old Genffsfile tools. Some code will be\r | |
348 | // added for\r | |
349 | // the different compressName;\r | |
350 | //\r | |
351 | Ch.UncompressLen = fileBuffer.length;\r | |
352 | Ch.CompressType = EFI_STANDARD_COMPRESSION;\r | |
353 | \r | |
354 | //\r | |
355 | // Change header struct to byte buffer\r | |
356 | //\r | |
357 | byte[] headerBuffer = new byte[Ch.GetSize()];\r | |
358 | Ch.StructToBuffer(headerBuffer);\r | |
359 | \r | |
360 | //\r | |
361 | // First add CompressHeader to Buffer, then add Compress\r | |
362 | // data.\r | |
363 | //\r | |
364 | buffer.write(headerBuffer);\r | |
365 | buffer.write(myCompress.outputBuffer);\r | |
366 | \r | |
367 | //\r | |
368 | // Buffer 4 Byte aligment\r | |
369 | //\r | |
370 | int size = Ch.GetSize() + myCompress.outputBuffer.length;\r | |
371 | \r | |
372 | while ((size & 0x03) != 0) {\r | |
373 | size++;\r | |
374 | buffer.writeByte(0);\r | |
375 | }\r | |
7dd2b2ad | 376 | }\r |
5c4eec41 | 377 | } catch (Exception e) {\r |
a1ffb10f | 378 | throw new BuildException("compress.toBuffer failed!\n");\r |
5c4eec41 | 379 | }\r |
a1ffb10f | 380 | } else {\r |
381 | Section sect;\r | |
382 | Iterator sectionIter = this.sectFileList.iterator();\r | |
383 | while (sectionIter.hasNext()) {\r | |
5c4eec41 | 384 | sect = (Section) sectionIter.next();\r |
a1ffb10f | 385 | try {\r |
386 | //\r | |
5c4eec41 | 387 | // The last section don't need 4 byte ffsAligment.\r |
a1ffb10f | 388 | //\r |
389 | sect.toBuffer(buffer);\r | |
390 | } catch (Exception e) {\r | |
5c4eec41 | 391 | throw new BuildException(e.getMessage());\r |
a1ffb10f | 392 | }\r |
393 | }\r | |
394 | }\r | |
395 | }\r | |
878ddf1f | 396 | }\r |