e329c0e3eb06d6cfe21edd5cc85c6f87f798eb81
[people/mcb30/edk2.git] / edk2 / Tools / Java / Source / FrameworkTasks / org / tianocore / framework / tasks / GenSectionTask.java
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
15 **/\r
16 \r
17 package org.tianocore.framework.tasks;\r
18 \r
19 import java.io.ByteArrayOutputStream;\r
20 import java.io.DataOutputStream;\r
21 import java.io.File;\r
22 import java.util.ArrayList;\r
23 import java.util.Iterator;\r
24 import java.util.List;\r
25 \r
26 import org.apache.tools.ant.BuildException;\r
27 import org.apache.tools.ant.Project;\r
28 import org.apache.tools.ant.Task;\r
29 import org.apache.tools.ant.taskdefs.Execute;\r
30 import org.apache.tools.ant.taskdefs.LogStreamHandler;\r
31 import org.apache.tools.ant.types.Commandline;\r
32 import org.tianocore.common.logger.EdkLog;\r
33 \r
34 public 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
39     //\r
40     // inputfile name\r
41     //\r
42     private FileArg inputFile = new FileArg();\r
43 \r
44     //\r
45     // outputfile name\r
46     //\r
47     private FileArg outputFile = new FileArg();\r
48 \r
49     //\r
50     // section type\r
51     //\r
52     private ToolArg sectionType = new ToolArg();\r
53 \r
54     //\r
55     // version number\r
56     //\r
57     private ToolArg versionNum = new ToolArg();\r
58 \r
59     //\r
60     // interface string\r
61     //\r
62     private ToolArg interfaceString = new ToolArg();\r
63 \r
64     //\r
65     // Section file list\r
66     //\r
67     private List<Section> sectFileList = new ArrayList<Section>();\r
68 \r
69     //\r
70     // flag indicated the <tool> element\r
71     //\r
72     private boolean haveTool = false;\r
73 \r
74     /**\r
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
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
88         String path = project.getProperty("env.FRAMEWORK_TOOLS_PATH");\r
89         if (path == null) {\r
90             command = toolName;\r
91         } else {\r
92             command = path + File.separator + toolName;\r
93         }\r
94         //\r
95         // argument of tools\r
96         //\r
97         String argument = "" + inputFile + outputFile + sectionType + versionNum + interfaceString;\r
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
114 \r
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
118 \r
119             revl = runner.execute();\r
120             if (EFI_SUCCESS == revl) {\r
121                 EdkLog.log(this, EdkLog.EDK_VERBOSE, toolName + " succeeded!");\r
122             } else {\r
123                 //\r
124                 // command execution fail\r
125                 //\r
126                 EdkLog.log(this, EdkLog.EDK_INFO, "ERROR = " + Integer.toHexString(revl));\r
127                 throw new BuildException(toolName + " failed!");\r
128             }\r
129         } catch (Exception e) {\r
130             throw new BuildException(e.getMessage());\r
131         }\r
132     }\r
133 \r
134     /**\r
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
141     public String getInputFile() {\r
142         return this.inputFile.getValue();\r
143     }\r
144 \r
145     /**\r
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
152     public void setInputFile(String inputFile) {\r
153         this.inputFile.setArg(" -i ", inputFile);\r
154     }\r
155 \r
156     /**\r
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
163     public String getOutputFile() {\r
164         return this.outputFile.getValue();\r
165     }\r
166 \r
167     /**\r
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
173     public void setOutputfile(String outputFile) {\r
174         this.outputFile.setArg(" -o ", outputFile);\r
175     }\r
176 \r
177     /**\r
178       getSectionType\r
179       \r
180       This function is to get class member "sectionType".\r
181       \r
182       @return                        sectoin type\r
183     **/\r
184     public String getSectionType() {\r
185         return this.sectionType.getValue();\r
186     }\r
187 \r
188     /**\r
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
195     public void setSectionType(String sectionType) {\r
196         this.sectionType.setArg(" -s ", sectionType);\r
197     }\r
198 \r
199     /**\r
200       getVersionNum\r
201       \r
202       This function is to get class member "versionNum".\r
203       @return                         version number\r
204     **/\r
205     public String getVersionNum() {\r
206         return this.versionNum.getValue();\r
207     }\r
208 \r
209     /**\r
210       setVersionNume\r
211       \r
212       This function is to set class member "versionNum".\r
213       @param versionNum               version number\r
214     **/\r
215     public void setVersionNum(String versionNum) {\r
216         this.versionNum.setArg(" -v ", versionNum);\r
217     }\r
218 \r
219     /**\r
220       getInterfaceString\r
221       \r
222       This function is to get class member "interfaceString".\r
223       @return                         interface string\r
224     **/\r
225     public String getInterfaceString() {\r
226         return this.interfaceString.getValue();\r
227     }\r
228 \r
229     /**\r
230       setInterfaceString\r
231       \r
232       This funcion is to set class member "interfaceString".\r
233       @param interfaceString            interface string\r
234     **/\r
235     public void setInterfaceString(String interfaceString) {\r
236         this.interfaceString.setArg(" -a ", "\"" + interfaceString + "\"");\r
237     }\r
238     \r
239     /**\r
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
247         this.sectFileList.add(sectFile);\r
248     }\r
249 \r
250     /**\r
251       setTool\r
252       \r
253       This function is to set the class member "Tool";\r
254       \r
255       @param tool \r
256     **/\r
257     public void addTool(Tool tool) {\r
258         this.sectFileList.add(tool);\r
259         this.haveTool = true;\r
260     }\r
261     \r
262     /**\r
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
269         this.sectFileList.add(task);\r
270     }\r
271     \r
272     public void toBuffer(DataOutputStream buffer){\r
273         //\r
274         // Search SectionList find earch section and call it's\r
275         // ToBuffer function.\r
276         //\r
277         if (this.sectionType.getValue().equalsIgnoreCase(\r
278                 "EFI_SECTION_COMPRESSION")\r
279                 && !this.haveTool) {\r
280             Section sect;\r
281 \r
282             //\r
283             // Get section file in compress node.\r
284             //\r
285             try {\r
286                 ByteArrayOutputStream bo = new ByteArrayOutputStream();\r
287                 DataOutputStream Do = new DataOutputStream(bo);\r
288 \r
289                 //\r
290                 // Get each section which under the compress {};\r
291                 // And add it is contains to File;\r
292                 //\r
293                 Iterator SectionIter = this.sectFileList.iterator();\r
294                 while (SectionIter.hasNext()) {\r
295                     sect = (Section) SectionIter.next();\r
296 \r
297                     //\r
298                     // Call each section class's toBuffer function.\r
299                     //\r
300                     try {\r
301                         sect.toBuffer(Do);\r
302                     } catch (BuildException e) {\r
303                         System.out.print(e.getMessage());\r
304                         throw new BuildException(\r
305                                 "Compress.toBuffer failed at section");\r
306                     } finally {\r
307                         if (Do != null){\r
308                             Do.close();\r
309                         }\r
310                     }\r
311                 }\r
312                 //\r
313                 // Call compress\r
314                 //\r
315                 byte[] fileBuffer = bo.toByteArray();\r
316 \r
317                 synchronized (CompressSection.semaphore) {\r
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
365                 }\r
366             } catch (Exception e) {\r
367                 throw new BuildException("GenSection<SectionType=EFI_SECTION_COMPRESSION> to Buffer  failed!\n");\r
368             } \r
369         } else {\r
370             Section sect;\r
371             Iterator sectionIter = this.sectFileList.iterator();\r
372             while (sectionIter.hasNext()) {\r
373                 sect = (Section) sectionIter.next();\r
374                 try {\r
375                     //\r
376                     // The last section don't need 4 byte ffsAligment.\r
377                     //\r
378                     sect.toBuffer(buffer);\r
379                 } catch (Exception e) {\r
380                     throw new BuildException(e.getMessage());\r
381                 }\r
382             }\r
383         }\r
384     }\r
385 }\r