anjana_sreekumar@infosys.com | 991c206 | 2020-01-08 11:42:57 +0530 | [diff] [blame^] | 1 | # Copyright 2019-present Infosys Limited |
| 2 | # SPDX-License-Identifier: Apache-2.0 |
| 3 | |
| 4 | |
| 5 | import re |
| 6 | import os |
| 7 | from template import Template |
| 8 | from xlUtils import xlUtils,wb |
| 9 | |
| 10 | ieFactoryData = {} |
| 11 | ieFactoryData['ieList'] = [] |
| 12 | |
| 13 | ieDataTypeData = {} |
| 14 | ieDataTypeData['ieTypeList'] = [] |
| 15 | ieDataTypeData['ieList'] = [] |
| 16 | class GenerateIeClass: |
| 17 | |
| 18 | def __init__( self ): |
| 19 | |
| 20 | self.ieParser() |
| 21 | |
| 22 | #Parse the data from excel sheet 'IE Modeling' |
| 23 | #and build to a dict 'iedata' |
| 24 | def ieParser(self): |
| 25 | |
| 26 | sheet = wb['IE Modeling'] |
| 27 | state = '' |
| 28 | |
| 29 | encodeSeq = [] |
| 30 | byteLength = 0 |
| 31 | currentType = '' |
| 32 | validation = '' |
| 33 | count = '' |
| 34 | decodeCondition = '' |
| 35 | encodeCondition = '' |
| 36 | typeVal = '' |
| 37 | presence = '' |
| 38 | bitLength = 0 |
| 39 | varDetailList = [] |
| 40 | ieData = dict() |
| 41 | ieTypeList = [] |
| 42 | lengthStr = '' |
| 43 | varType = '' |
| 44 | varName = '' |
| 45 | mType=0 |
| 46 | varList=[] |
| 47 | grpIeList = [] |
| 48 | |
| 49 | for i in range(1,sheet.max_row+1): |
| 50 | presence = '' |
| 51 | bitLength = 0 |
| 52 | byteLength = 0 |
| 53 | cell_value_B = xlUtils.getCellValue(sheet,i,'B') |
| 54 | cell_value_D = xlUtils.getCellValue(sheet,i,'D') |
| 55 | cell_value_H = xlUtils.getCellValue(sheet,i,'H') |
| 56 | |
| 57 | # Search pattern for IE definition start,end |
| 58 | mGroupedIe = re.search('Grouped IE Definition:(\w+)',str(cell_value_B)) |
| 59 | mIeDefStart = re.search('IE Definition Start:(\w+)',str(cell_value_B)) |
| 60 | mIeDefEnd = re.search('IE Definition End:(\w+)' ,str(cell_value_B)) |
| 61 | |
| 62 | if mGroupedIe: |
| 63 | |
| 64 | grpIeName = mGroupedIe.group(1) |
| 65 | grpIeList.append(grpIeName) |
| 66 | for grpie in grpIeList: |
| 67 | self.generateIeFactory(grpie) |
| 68 | |
| 69 | if mIeDefStart: |
| 70 | currentType = mIeDefStart.group(1) |
| 71 | state = 'StartDetected' |
| 72 | ieTypeList.append(currentType) |
| 73 | |
| 74 | elif mIeDefEnd: |
| 75 | |
| 76 | state = 'EndDetected' |
| 77 | self.templateIes(ieData,currentType) |
| 78 | self.generateIeFactory(currentType) |
| 79 | self.generateIeDataType(currentType,typeVal,varList) |
| 80 | self.prepareIeMakeFile() |
| 81 | varList = [] |
| 82 | |
| 83 | elif state == 'StartDetected': |
| 84 | varDetailList = [] |
| 85 | encodeSeq = [] |
| 86 | |
| 87 | colDValue = str(cell_value_D) |
| 88 | mType = re.search('Type = (\d+)',colDValue) |
| 89 | mSpare = re.search('Spare',colDValue) |
| 90 | mInstance = re.search('Instance',str(cell_value_H)) |
| 91 | |
| 92 | if mType: |
| 93 | typeVal = mType.group(1) |
| 94 | ieData['ieDetails'] = {} |
| 95 | ieData['ieDetails'][currentType] = {} |
| 96 | ieData['ieDetails'][currentType]['ieName'] = currentType |
| 97 | ieData['ieDetails'][currentType]['ieTypeVal'] = typeVal |
| 98 | |
| 99 | if mSpare and mInstance: |
| 100 | state = 'TypeDefinitionStart' |
| 101 | |
| 102 | elif state == 'TypeDefinitionStart': |
| 103 | |
| 104 | (byteLength,lengthStr) = xlUtils.getByteLength(sheet,i) |
| 105 | |
| 106 | #for fields less than 1 bytelength |
| 107 | if byteLength == 0: |
| 108 | |
| 109 | for j in map(chr, range( ord('D'), ord('L'))): |
| 110 | field = xlUtils.getCellValue(sheet,i,j) |
| 111 | fieldDetails=dict() |
| 112 | if field != None: |
| 113 | |
| 114 | bitLength = xlUtils.getBitLength(sheet,i,j) |
| 115 | (varName,varType,encodeCondition,decodeCondition,validation,count) = xlUtils.extractField(field) |
| 116 | |
| 117 | if varType == '': |
| 118 | varType = 'Uint8' |
| 119 | if bitLength == 8: |
| 120 | byteLength = 1 |
| 121 | bitLength = 0 |
| 122 | if varName != 'Spare': |
| 123 | fieldDetails['varName']=varName |
| 124 | fieldDetails['varType']=varType |
| 125 | fieldDetails['presence']=presence |
| 126 | varList.append(fieldDetails) |
| 127 | |
| 128 | ieData['varDetails'] = {} |
| 129 | ieData['varDetails'][varName] = {} |
| 130 | ieData['varDetails'][varName]['varType'] = varType |
| 131 | ieData['varDetails'][varName]['decodeCondition'] = decodeCondition |
| 132 | ieData['varDetails'][varName]['encodeCondition'] = encodeCondition |
| 133 | ieData['varDetails'][varName]['validation'] = validation |
| 134 | ieData['varDetails'][varName]['bitLength'] = bitLength |
| 135 | ieData['varDetails'][varName]['byteLength'] = byteLength |
| 136 | ieData['varDetails'][varName]['lengthStr'] = lengthStr |
| 137 | ieData['varDetails'][varName]['presence'] = presence |
| 138 | ieData['varDetails'][varName]['count'] = count |
| 139 | varDetailList.append(ieData['varDetails']) |
| 140 | ieData['varDetails'] = varDetailList |
| 141 | |
| 142 | encStrBit = 'encode:' + varName + ':' + str(bitLength) + ':Bits' |
| 143 | encodeSeq.append(encStrBit) |
| 144 | ieData['encodeSeq'] = encodeSeq |
| 145 | |
| 146 | else: |
| 147 | skipStrBit = 'skip:'+ str(bitLength) + ':Bits' |
| 148 | encodeSeq.append(skipStrBit) |
| 149 | ieData['encodeSeq'] = encodeSeq |
| 150 | |
| 151 | #for fields of length 1 byte |
| 152 | else: |
| 153 | |
| 154 | field = sheet.cell(row=i, column=4).value |
| 155 | (varName,varType,encodeCondition,decodeCondition,validation,count) = xlUtils.extractField(field) |
| 156 | fieldDetails=dict() |
| 157 | if varType == '': |
| 158 | varType = xlUtils.lengthToType(byteLength) |
| 159 | |
| 160 | if varName != 'Spare': |
| 161 | fieldDetails['varName']=varName |
| 162 | fieldDetails['varType']=varType |
| 163 | if xlUtils.getCellValue(sheet,i,'B') == 'Yes': |
| 164 | presence = 'optional' |
| 165 | fieldDetails['presence']=presence |
| 166 | varList.append(fieldDetails) |
| 167 | |
| 168 | ieData['varDetails'] = {} |
| 169 | ieData['varDetails'][varName] = {} |
| 170 | ieData['varDetails'][varName]['varType'] = varType |
| 171 | ieData['varDetails'][varName]['decodeCondition'] = decodeCondition |
| 172 | ieData['varDetails'][varName]['encodeCondition'] = encodeCondition |
| 173 | ieData['varDetails'][varName]['validation'] = validation |
| 174 | ieData['varDetails'][varName]['bitLength'] = bitLength |
| 175 | ieData['varDetails'][varName]['byteLength'] = byteLength |
| 176 | ieData['varDetails'][varName]['lengthStr'] = lengthStr |
| 177 | ieData['varDetails'][varName]['count'] = count |
| 178 | |
| 179 | if xlUtils.getCellValue(sheet,i,'B') == 'Yes': |
| 180 | presence = 'optional' |
| 181 | |
| 182 | ieData['varDetails'][varName]['presence'] = presence |
| 183 | varDetailList.append(ieData['varDetails']) |
| 184 | ieData['varDetails'] = varDetailList |
| 185 | |
| 186 | encstrbyte = 'encode:' + varName + ':' + str(byteLength) + ':Bytes' |
| 187 | encodeSeq.append(encstrbyte) |
| 188 | ieData['encodeSeq'] = encodeSeq |
| 189 | else: |
| 190 | skipstrbyte = 'skip:'+ str(byteLength) + ':Bytes' |
| 191 | encodeSeq.append(skipstrbyte) |
| 192 | ieData['encodeSeq'] = encodeSeq |
| 193 | return ieData |
| 194 | |
| 195 | def templateIes(self,ieData,currentType): |
| 196 | |
| 197 | templateData = dict() |
| 198 | varDetailsList = [] |
| 199 | sequenceList = [] |
| 200 | varDetailsList = ieData['varDetails'] |
| 201 | templateData['className'] = ieData['ieDetails'][currentType]['ieName']+'Ie' |
| 202 | templateData['fileName'] = templateData['className'][0].lower() + templateData['className'][1:] |
| 203 | templateData['classNameUC'] = templateData['className'].upper() |
| 204 | templateData['ieTypeVal'] = ieData['ieDetails'][currentType]['ieTypeVal'] |
| 205 | |
| 206 | #building the dictionary obtained to a dict 'templateData' |
| 207 | #which is the input to template process |
| 208 | |
| 209 | for en in ieData['encodeSeq']: |
| 210 | mEncode = re.search('encode:(\w+):',en) |
| 211 | mSkip = re.search('skip:(\d+):(\w+)',en) |
| 212 | item = dict() |
| 213 | if mSkip: |
| 214 | bitByte = mSkip.group(2) |
| 215 | skipValue = mSkip.group(1) |
| 216 | item['skipType'] = 'y' |
| 217 | item['bitByte'] = bitByte |
| 218 | item['skipValue'] = skipValue |
| 219 | elif mEncode: |
| 220 | varName = mEncode.group(1) |
| 221 | for variableDetails in varDetailsList: |
| 222 | for key,value in variableDetails.items(): |
| 223 | if key == varName: |
| 224 | item['fieldName'] = varName |
| 225 | if value['bitLength'] != 0: |
| 226 | item['bitField'] = 'y' |
| 227 | item['fieldSize'] = value['bitLength'] |
| 228 | item['leafType'] = 'y' |
| 229 | else: |
| 230 | item['fieldSize'] = value['byteLength'] |
| 231 | if value['decodeCondition'] != '': |
| 232 | item['decodeConditional'] = 'y' |
| 233 | item['decodeCondition'] = value['decodeCondition'] |
| 234 | if value['encodeCondition'] != '': |
| 235 | item['encodeConditional'] = 'y' |
| 236 | item['encodeCondition'] = value['encodeCondition'] |
| 237 | if value.get('presence') == 'optional': |
| 238 | item['presence'] = 'optional' |
| 239 | item['fieldType'] = value['varType'] |
| 240 | mUint = re.search('^Uint(\d+)$',value['varType']) |
| 241 | if mUint or value['varType'] == 'bool': |
| 242 | item['leafType'] = 'y' |
| 243 | else: |
| 244 | if value['lengthStr'] == 'EOI' or value['lengthStr'] == '': |
| 245 | item['length'] = 'lengthLeft' |
| 246 | else: |
| 247 | item['length'] = value['lengthStr'] |
| 248 | if value['validation'] != '': |
| 249 | |
| 250 | item['validationPresent'] = 'y' |
| 251 | item['validationRule'] = value['validation'] |
| 252 | mArray = re.search('Array',value['varType']) |
| 253 | if mArray: |
| 254 | item['arrayType']='y' |
| 255 | if value['count'] =='': |
| 256 | item['count']=0 |
| 257 | else: |
| 258 | item['count']=value['count'] |
| 259 | |
| 260 | if item != {}: |
| 261 | sequenceList.append(item) |
| 262 | templateData['sequence'] = sequenceList |
| 263 | |
| 264 | outputDir = '../../src/gtpV2Codec/ieClasses' |
| 265 | ttFileNameCpp = 'tts/ietemplate.cpp.tt' |
| 266 | ttFileNameH = 'tts/ietemplate.h.tt' |
| 267 | xlUtils.templateProcess(templateData,ttFileNameCpp,ttFileNameH,outputDir,outputDir) |
| 268 | |
| 269 | objectFile = 'ieClasses/' +templateData['fileName'] + '.o' |
| 270 | sourceFile ='ieClasses/' + templateData['fileName'] + '.cpp' |
| 271 | xlUtils.addToMakeSo('gtpV2Stack.so',objectFile,sourceFile) |
| 272 | |
| 273 | def ieFactoryTemplate(self,ieFactoryData): |
| 274 | |
| 275 | ieFactoryData['fileName']='gtpV2IeFactory' |
| 276 | ttFileNameFactoryCpp = 'tts/iefactorytemplate.cpp.tt' |
| 277 | outputDir = '../../src/gtpV2Codec/ieClasses' |
| 278 | ttFileNamefactoryH = 'tts/iefactorytemplate.h.tt' |
| 279 | xlUtils.templateProcess(ieFactoryData,ttFileNameFactoryCpp,ttFileNamefactoryH,outputDir,outputDir) |
| 280 | |
| 281 | def generateIeFactory(self,currentType): |
| 282 | ieinfo = {} |
| 283 | ieinfo['className'] = currentType + 'Ie' |
| 284 | ieinfo['ieFileName'] = currentType[0].lower()+currentType[1:] + 'Ie' |
| 285 | if ieinfo not in ieFactoryData['ieList']: |
| 286 | ieFactoryData['ieList'].append(ieinfo) |
| 287 | outputDir = 'ieClasses/' |
| 288 | self.ieFactoryTemplate(ieFactoryData) |
| 289 | xlUtils.addToMakeSo('gtpV2Stack.so',outputDir+'gtpV2IeFactory.o',outputDir+'gtpV2IeFactory.cpp') |
| 290 | |
| 291 | def generateIeDataType(self,currentType,typeVal,varList): |
| 292 | ieinfo = {} |
| 293 | ieTypeInfo={} |
| 294 | ieinfo['ieName'] = currentType + 'IeData' |
| 295 | ieinfo['varList'] = varList |
| 296 | ieTypeInfo['ieName']=currentType + 'IeType' |
| 297 | ieTypeInfo['value']=typeVal |
| 298 | if ieinfo not in ieDataTypeData['ieList']: |
| 299 | ieDataTypeData['ieList'].append(ieinfo) |
| 300 | if ieTypeInfo not in ieDataTypeData['ieTypeList']: |
| 301 | ieDataTypeData['ieTypeList'].append(ieTypeInfo) |
| 302 | #print(ieDataTypeData) |
| 303 | template = Template() |
| 304 | ttFileNamefactoryH = 'tts/ieDataTypetemplate.h.tt' |
| 305 | outputDir = '../../src/gtpV2Codec/ieClasses' |
| 306 | |
| 307 | if not os.path.exists(outputDir): |
| 308 | os.makedirs(outputDir) |
| 309 | outputFileName = 'gtpV2IeDataTypes.h' |
| 310 | template.__init__({'OUTPUT' : outputFileName, 'OUTPUT_PATH' : outputDir}) |
| 311 | template.process(ttFileNamefactoryH, {'tempdata' : ieDataTypeData}) |
| 312 | |
| 313 | def prepareIeMakeFile(self): |
| 314 | outputDir = 'ieClasses/' |
| 315 | xlUtils.addToMakeSo('gtpV2Stack.so', outputDir+'dataTypeCodecUtils.o', outputDir+'dataTypeCodecUtils.cpp') |
| 316 | xlUtils.addToMakeSo('gtpV2Stack.so', outputDir+'manual/gtpV2Ie.o', outputDir+'manual/gtpV2Ie.cpp') |
| 317 | |
| 318 | GenerateIeClass() |