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