BaseTools: Replace StringIO.StringIO with io.BytesIO
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsFileStatement.py
1 ## @file
2 # process FFS generation from FILE statement
3 #
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 #
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 ##
16 # Import Modules
17 #
18 import Ffs
19 import Rule
20 import Common.LongFilePathOs as os
21 from io import BytesIO
22 import subprocess
23
24 from GenFdsGlobalVariable import GenFdsGlobalVariable
25 from CommonDataClass.FdfClass import FileStatementClassObject
26 from Common import EdkLogger
27 from Common.BuildToolError import *
28 from Common.Misc import GuidStructureByteArrayToGuidString
29 from GuidSection import GuidSection
30 from FvImageSection import FvImageSection
31 from Common.Misc import SaveFileOnChange
32 from struct import *
33
34 ## generate FFS from FILE
35 #
36 #
37 class FileStatement (FileStatementClassObject) :
38 ## The constructor
39 #
40 # @param self The object pointer
41 #
42 def __init__(self):
43 FileStatementClassObject.__init__(self)
44 self.CurrentLineNum = None
45 self.CurrentLineContent = None
46 self.FileName = None
47 self.InfFileName = None
48 self.SubAlignment = None
49
50 ## GenFfs() method
51 #
52 # Generate FFS
53 #
54 # @param self The object pointer
55 # @param Dict dictionary contains macro and value pair
56 # @param FvChildAddr Array of the inside FvImage base address
57 # @param FvParentAddr Parent Fv base address
58 # @retval string Generated FFS file name
59 #
60 def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None, IsMakefile=False, FvName=None):
61
62 if self.NameGuid is not None and self.NameGuid.startswith('PCD('):
63 PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)
64 if len(PcdValue) == 0:
65 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
66 % (self.NameGuid))
67 if PcdValue.startswith('{'):
68 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
69 RegistryGuidStr = PcdValue
70 if len(RegistryGuidStr) == 0:
71 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
72 % (self.NameGuid))
73 self.NameGuid = RegistryGuidStr
74
75 Str = self.NameGuid
76 if FvName:
77 Str += FvName
78 OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, Str)
79 if not os.path.exists(OutputDir):
80 os.makedirs(OutputDir)
81
82 Dict.update(self.DefineVarDict)
83 SectionAlignments = None
84 if self.FvName is not None :
85 Buffer = BytesIO('')
86 if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
87 EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName))
88 Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
89 FileName = Fv.AddToBuffer(Buffer)
90 SectionFiles = [FileName]
91
92 elif self.FdName is not None:
93 if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
94 EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName))
95 Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper())
96 FileName = Fd.GenFd()
97 SectionFiles = [FileName]
98
99 elif self.FileName is not None:
100 if hasattr(self, 'FvFileType') and self.FvFileType == 'RAW':
101 if isinstance(self.FileName, list) and isinstance(self.SubAlignment, list) and len(self.FileName) == len(self.SubAlignment):
102 FileContent = ''
103 MaxAlignIndex = 0
104 MaxAlignValue = 1
105 for Index, File in enumerate(self.FileName):
106 try:
107 f = open(File, 'rb')
108 except:
109 GenFdsGlobalVariable.ErrorLogger("Error opening RAW file %s." % (File))
110 Content = f.read()
111 f.close()
112 AlignValue = 1
113 if self.SubAlignment[Index] is not None:
114 AlignValue = GenFdsGlobalVariable.GetAlignment(self.SubAlignment[Index])
115 if AlignValue > MaxAlignValue:
116 MaxAlignIndex = Index
117 MaxAlignValue = AlignValue
118 FileContent += Content
119 if len(FileContent) % AlignValue != 0:
120 Size = AlignValue - len(FileContent) % AlignValue
121 for i in range(0, Size):
122 FileContent += pack('B', 0xFF)
123
124 if FileContent:
125 OutputRAWFile = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid, self.NameGuid + '.raw')
126 SaveFileOnChange(OutputRAWFile, FileContent, True)
127 self.FileName = OutputRAWFile
128 self.SubAlignment = self.SubAlignment[MaxAlignIndex]
129
130 if self.Alignment and self.SubAlignment:
131 if GenFdsGlobalVariable.GetAlignment (self.Alignment) < GenFdsGlobalVariable.GetAlignment (self.SubAlignment):
132 self.Alignment = self.SubAlignment
133 elif self.SubAlignment:
134 self.Alignment = self.SubAlignment
135
136 self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
137 #Replace $(SAPCE) with real space
138 self.FileName = self.FileName.replace('$(SPACE)', ' ')
139 SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)]
140
141 else:
142 SectionFiles = []
143 Index = 0
144 SectionAlignments = []
145 for section in self.SectionList :
146 Index = Index + 1
147 SecIndex = '%d' %Index
148 # process the inside FvImage from FvSection or GuidSection
149 if FvChildAddr != []:
150 if isinstance(section, FvImageSection):
151 section.FvAddr = FvChildAddr.pop(0)
152 elif isinstance(section, GuidSection):
153 section.FvAddr = FvChildAddr
154 if FvParentAddr is not None and isinstance(section, GuidSection):
155 section.FvParentAddr = FvParentAddr
156
157 if self.KeepReloc == False:
158 section.KeepReloc = False
159 sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict)
160 if sectList != []:
161 for sect in sectList:
162 SectionFiles.append(sect)
163 SectionAlignments.append(align)
164
165 #
166 # Prepare the parameter
167 #
168 FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs')
169 GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles,
170 Ffs.Ffs.FdfFvFileTypeToFileType.get(self.FvFileType),
171 self.NameGuid,
172 Fixed=self.Fixed,
173 CheckSum=self.CheckSum,
174 Align=self.Alignment,
175 SectionAlign=SectionAlignments
176 )
177
178 return FfsFileOutput
179
180
181