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