add .. support
[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
5c4eec41 15 **/\r
878ddf1f 16\r
17package org.tianocore.framework.tasks;\r
18\r
a1ffb10f 19import java.io.ByteArrayOutputStream;\r
20import java.io.DataOutputStream;\r
a1ffb10f 21import java.util.ArrayList;\r
22import java.util.Iterator;\r
23import java.util.List;\r
219e2247 24\r
25import org.apache.tools.ant.BuildException;\r
878ddf1f 26import org.apache.tools.ant.Project;\r
27import org.apache.tools.ant.Task;\r
878ddf1f 28import org.apache.tools.ant.taskdefs.Execute;\r
29import org.apache.tools.ant.taskdefs.LogStreamHandler;\r
30import org.apache.tools.ant.types.Commandline;\r
a1ffb10f 31import org.tianocore.common.logger.EdkLog;\r
878ddf1f 32\r
5c4eec41 33public 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