BaseTools: Replace StringIO.StringIO with io.BytesIO
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / ValidCheckingInfoObject.py
1 # Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
2 # This program and the accompanying materials
3 # are licensed and made available under the terms and conditions of the BSD License
4 # which accompanies this distribution. The full text of the license may be found at
5 # http://opensource.org/licenses/bsd-license.php
6 #
7 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
8 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
9
10 #
11 # This file is used to collect the Variable checking information
12 #
13
14 # #
15 # Import Modules
16 #
17 import os
18 from Common.RangeExpression import RangeExpression
19 from Common.Misc import *
20 from io import BytesIO
21 from struct import pack
22 from Common.DataType import *
23
24 class VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER(object):
25 def __init__(self):
26 self.var_check_info = []
27
28 def push_back(self, var_check_tab):
29 for tab in self.var_check_info:
30 if tab.equal(var_check_tab):
31 tab.merge(var_check_tab)
32 break
33 else:
34 self.var_check_info.append(var_check_tab)
35
36 def dump(self, dest, Phase):
37
38 if not os.path.isabs(dest):
39 return
40 if not os.path.exists(dest):
41 os.mkdir(dest)
42 BinFileName = "PcdVarCheck.bin"
43 BinFilePath = os.path.join(dest, BinFileName)
44 Buffer = ''
45 index = 0
46 for var_check_tab in self.var_check_info:
47 index += 1
48 realLength = 0
49 realLength += 32
50 Name = var_check_tab.Name[1:-1]
51 NameChars = Name.split(",")
52 realLength += len(NameChars)
53 if (index < len(self.var_check_info) and realLength % 4) or (index == len(self.var_check_info) and len(var_check_tab.validtab) > 0 and realLength % 4):
54 realLength += (4 - (realLength % 4))
55 itemIndex = 0
56 for item in var_check_tab.validtab:
57 itemIndex += 1
58 realLength += 5
59 for v_data in item.data:
60 if type(v_data) in (int, long):
61 realLength += item.StorageWidth
62 else:
63 realLength += item.StorageWidth
64 realLength += item.StorageWidth
65 if (index == len(self.var_check_info)) :
66 if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:
67 realLength += (4 - (realLength % 4))
68 else:
69 if realLength % 4:
70 realLength += (4 - (realLength % 4))
71 var_check_tab.Length = realLength
72 realLength = 0
73 index = 0
74 for var_check_tab in self.var_check_info:
75 index += 1
76
77 b = pack("=H", var_check_tab.Revision)
78 Buffer += b
79 realLength += 2
80
81 b = pack("=H", var_check_tab.HeaderLength)
82 Buffer += b
83 realLength += 2
84
85 b = pack("=L", var_check_tab.Length)
86 Buffer += b
87 realLength += 4
88
89 b = pack("=B", var_check_tab.Type)
90 Buffer += b
91 realLength += 1
92
93 for i in range(0, 3):
94 b = pack("=B", var_check_tab.Reserved)
95 Buffer += b
96 realLength += 1
97
98 b = pack("=L", var_check_tab.Attributes)
99 Buffer += b
100 realLength += 4
101
102 Guid = var_check_tab.Guid
103 b = PackByteFormatGUID(Guid)
104 Buffer += b
105 realLength += 16
106
107 Name = var_check_tab.Name[1:-1]
108 NameChars = Name.split(",")
109 for NameChar in NameChars:
110 NameCharNum = int(NameChar, 16)
111 b = pack("=B", NameCharNum)
112 Buffer += b
113 realLength += 1
114
115 if (index < len(self.var_check_info) and realLength % 4) or (index == len(self.var_check_info) and len(var_check_tab.validtab) > 0 and realLength % 4):
116 for i in range(4 - (realLength % 4)):
117 b = pack("=B", var_check_tab.pad)
118 Buffer += b
119 realLength += 1
120 itemIndex = 0
121 for item in var_check_tab.validtab:
122 itemIndex += 1
123
124 b = pack("=B", item.Type)
125 Buffer += b
126 realLength += 1
127
128 b = pack("=B", item.Length)
129 Buffer += b
130 realLength += 1
131
132 b = pack("=H", int(item.VarOffset, 16))
133 Buffer += b
134 realLength += 2
135
136 b = pack("=B", item.StorageWidth)
137 Buffer += b
138 realLength += 1
139 for v_data in item.data:
140 if type(v_data) in (int, long):
141 b = pack(PACK_CODE_BY_SIZE[item.StorageWidth], v_data)
142 Buffer += b
143 realLength += item.StorageWidth
144 else:
145 b = pack(PACK_CODE_BY_SIZE[item.StorageWidth], v_data[0])
146 Buffer += b
147 realLength += item.StorageWidth
148 b = pack(PACK_CODE_BY_SIZE[item.StorageWidth], v_data[1])
149 Buffer += b
150 realLength += item.StorageWidth
151
152 if (index == len(self.var_check_info)) :
153 if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:
154 for i in range(4 - (realLength % 4)):
155 b = pack("=B", var_check_tab.pad)
156 Buffer += b
157 realLength += 1
158 else:
159 if realLength % 4:
160 for i in range(4 - (realLength % 4)):
161 b = pack("=B", var_check_tab.pad)
162 Buffer += b
163 realLength += 1
164
165 DbFile = BytesIO()
166 if Phase == 'DXE' and os.path.exists(BinFilePath):
167 BinFile = open(BinFilePath, "rb")
168 BinBuffer = BinFile.read()
169 BinFile.close()
170 BinBufferSize = len(BinBuffer)
171 if (BinBufferSize % 4):
172 for i in range(4 - (BinBufferSize % 4)):
173 b = pack("=B", VAR_CHECK_PCD_VARIABLE_TAB.pad)
174 BinBuffer += b
175 Buffer = BinBuffer + Buffer
176 DbFile.write(Buffer)
177 SaveFileOnChange(BinFilePath, DbFile.getvalue(), True)
178
179
180 class VAR_CHECK_PCD_VARIABLE_TAB(object):
181 pad = 0xDA
182 def __init__(self, TokenSpaceGuid, PcdCName):
183 self.Revision = 0x0001
184 self.HeaderLength = 0
185 self.Length = 0 # Length include this header
186 self.Type = 0
187 self.Reserved = 0
188 self.Attributes = 0x00000000
189 self.Guid = eval("[" + TokenSpaceGuid.replace("{", "").replace("}", "") + "]")
190 self.Name = PcdCName
191 self.validtab = []
192
193 def UpdateSize(self):
194 self.HeaderLength = 32 + len(self.Name.split(","))
195 self.Length = 32 + len(self.Name.split(",")) + self.GetValidTabLen()
196
197 def GetValidTabLen(self):
198 validtablen = 0
199 for item in self.validtab:
200 validtablen += item.Length
201 return validtablen
202
203 def SetAttributes(self, attributes):
204 self.Attributes = attributes
205
206 def push_back(self, valid_obj):
207 if valid_obj is not None:
208 self.validtab.append(valid_obj)
209
210 def equal(self, varchecktab):
211 if self.Guid == varchecktab.Guid and self.Name == varchecktab.Name:
212 return True
213 else:
214 return False
215
216 def merge(self, varchecktab):
217 for validobj in varchecktab.validtab:
218 if validobj in self.validtab:
219 continue
220 self.validtab.append(validobj)
221 self.UpdateSize()
222
223
224 class VAR_CHECK_PCD_VALID_OBJ(object):
225 def __init__(self, VarOffset, data, PcdDataType):
226 self.Type = 1
227 self.Length = 0 # Length include this header
228 self.VarOffset = VarOffset
229 self.PcdDataType = PcdDataType.strip()
230 self.rawdata = data
231 self.data = set()
232 try:
233 self.StorageWidth = MAX_SIZE_TYPE[self.PcdDataType]
234 self.ValidData = True
235 except:
236 self.StorageWidth = 0
237 self.ValidData = False
238
239 def __eq__(self, validObj):
240 return validObj and self.VarOffset == validObj.VarOffset
241
242 class VAR_CHECK_PCD_VALID_LIST(VAR_CHECK_PCD_VALID_OBJ):
243 def __init__(self, VarOffset, validlist, PcdDataType):
244 super(VAR_CHECK_PCD_VALID_LIST, self).__init__(VarOffset, validlist, PcdDataType)
245 self.Type = 1
246 valid_num_list = []
247 for item in self.rawdata:
248 valid_num_list.extend(item.split(','))
249
250 for valid_num in valid_num_list:
251 valid_num = valid_num.strip()
252
253 if valid_num.startswith('0x') or valid_num.startswith('0X'):
254 self.data.add(int(valid_num, 16))
255 else:
256 self.data.add(int(valid_num))
257
258
259 self.Length = 5 + len(self.data) * self.StorageWidth
260
261
262 class VAR_CHECK_PCD_VALID_RANGE(VAR_CHECK_PCD_VALID_OBJ):
263 def __init__(self, VarOffset, validrange, PcdDataType):
264 super(VAR_CHECK_PCD_VALID_RANGE, self).__init__(VarOffset, validrange, PcdDataType)
265 self.Type = 2
266 RangeExpr = ""
267 i = 0
268 for item in self.rawdata:
269 if i == 0:
270 RangeExpr = "( " + item + " )"
271 else:
272 RangeExpr = RangeExpr + "OR ( " + item + " )"
273 range_result = RangeExpression(RangeExpr, self.PcdDataType)(True)
274 for rangelist in range_result:
275 for obj in rangelist.pop():
276 self.data.add((obj.start, obj.end))
277 self.Length = 5 + len(self.data) * 2 * self.StorageWidth
278
279
280 def GetValidationObject(PcdClass, VarOffset):
281 if PcdClass.validateranges:
282 return VAR_CHECK_PCD_VALID_RANGE(VarOffset, PcdClass.validateranges, PcdClass.DatumType)
283 if PcdClass.validlists:
284 return VAR_CHECK_PCD_VALID_LIST(VarOffset, PcdClass.validlists, PcdClass.DatumType)
285 else:
286 return None