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