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