How to use _getAttribute method in pyatom

Best Python code snippet using pyatom_python

parser.py

Source:parser.py Github

copy

Full Screen

...56 else:57 self._configs = configs58 def _getBooleanAttribute(self, node, name):59 """If node has no attribute named |name| return True."""60 v = self._getAttribute(node, name)61 if not v:62 return True63 v = v.lower()64 r = v in ('true', 'yes', '1')65 if not r:66 assert v in ('false', 'no', '0')67 return r68 def substituteConfigVariables(self, xmlString, final=False):69 result = []70 pos = 071 numVarsLeft = 072 numVarsFound = 073 unresolved = []74 if not final:75 logging.info("Analyzing XML for potential macros.")76 for m in re.finditer(r"\$(\w+:?\w*)\$", xmlString):77 result.append(xmlString[pos:m.start(0)])78 varName = m.group(1)79 handled = False80 if varName in self._configs:81 logging.debug('Setting "{}" to "{}"'.format(varName, self._configs[varName]))82 result.append(self._configs[varName])83 handled = True84 elif ':' in varName:85 # Instance provider86 (instanceProviderName, identifier) = varName.split(':')87 instanceProvider = getInstanceProvider(instanceProviderName)88 try:89 instance = str(instanceProvider.getInstanceById(identifier, self._configs))90 logging.debug('Setting "{}" to "{}"'.format(varName, instance))91 result.append(instance)92 handled = True93 except Exception:94 # allow it to fail for now, probably need other macros to resolve this95 pass96 if not handled:97 result.append(m.group(0))98 unresolved.append(m.group(1))99 numVarsLeft += 1100 pos = m.end(0)101 numVarsFound += 1102 result.append(xmlString[pos:])103 if not final:104 logging.info("Found {} macros, {} resolved.".format(numVarsFound, numVarsFound - numVarsLeft))105 elif unresolved:106 for u in unresolved:107 logging.warning("Unresolved macro: %s" % u)108 return "".join(result)109 def parse(self, uri):110 """111 Parse a Peach XML file pointed to by uri.112 """113 logging.info(highlight.info("Parsing %s" % uri))114 doc = etree.parse(uri, parser=self._parser, base_url="http://phed.org").getroot()115 if "_target" in self._configs:116 target = etree.parse(self._configs["_target"], parser=self._parser, base_url="http://phed.org").getroot()117 if split_ns(target.tag)[1] != 'Peach':118 raise PeachException("First element in document must be Peach, not '%s'" % target.tag)119 for child in target.iterchildren():120 doc.append(child)121 del self._configs["_target"]122 # try early to find configuration macros123 self.FindConfigurations(doc)124 xmlString = etree.tostring(doc)125 return self.parseString(xmlString, findConfigs=False)126 def parseString(self, xml, findConfigs=True):127 """128 Parse a string as Peach XML.129 """130 xml = self.substituteConfigVariables(xml)131 doc = etree.fromstring(xml, parser=self._parser, base_url="http://phed.org")132 return self.HandleDocument(doc, findConfigs=findConfigs)133 def GetClassesInModule(self, module):134 """135 Return array of class names in module136 """137 classes = []138 for item in dir(module):139 i = getattr(module, item)140 if type(i) == type and item[0] != '_':141 classes.append(item)142 elif type(i) == types.MethodType and item[0] != '_':143 classes.append(item)144 elif type(i) == types.FunctionType and item[0] != '_':145 classes.append(item)146 elif repr(i).startswith("<class"):147 classes.append(item)148 return classes149 def FindConfigurations(self, doc):150 # FIRST check for a configuration section. If one exists, we need to parse it and then restart.151 #print "Looking for Configuration element"152 has_config = False153 for child in doc.iterchildren():154 child_tag = split_ns(child.tag)[1]155 if child_tag != 'Configuration':156 continue157 #assert not has_config, "Multiple <Configuration> elements"158 has_config = True159 #print "Found Configuration element"160 for child in child.iterchildren():161 child_tag = split_ns(child.tag)[1]162 assert child_tag == "Macro", "Unknown child in Configuration element: {}".format(child_tag)163 name = child.get("name")164 if name not in self._configs:165 #print "\t%s = %s" % (name, child.get("value"))166 self._configs[name] = child.get("value")167 else:168 #print "\t%s = %s [dropped]" % (name, child.get("value"))169 pass170 return has_config171 def HandleDocument(self, doc, uri="", findConfigs=True):172 if findConfigs and self.FindConfigurations(doc):173 return self.parseString(etree.tostring(doc), findConfigs=False)174 #self.StripComments(doc)175 self.StripText(doc)176 ePeach = doc177 if split_ns(ePeach.tag)[1] != 'Peach':178 raise PeachException("First element in document must be Peach, not '%s'" % ePeach.tag)179 peach = dom.Peach()180 peach.peachPitUri = uri181 #peach.node = doc182 self.context = peach183 peach.mutators = None184 #: List of nodes that need some parse love list of [xmlNode, parent]185 self.unfinishedReferences = []186 for i in ['templates', 'data', 'agents', 'namespaces', 'tests', 'runs']:187 setattr(peach, i, ElementWithChildren())188 # Peach attributes189 for i in ['version', 'author', 'description']:190 setattr(peach, i, self._getAttribute(ePeach, i))191 # The good stuff -- We are going todo multiple passes here to increase the likely hood192 # that things will turn out okay.193 # Pass 1 -- Include, PythonPath, Defaults194 for child in ePeach.iterchildren():195 child_tag = split_ns(child.tag)[1]196 if child_tag == 'Include':197 # Include this file198 nsName = self._getAttribute(child, 'ns')199 nsSrc = self._getAttribute(child, 'src')200 parser = ParseTemplate(self._configs)201 ns = parser.parse(nsSrc)202 ns.name = nsName + ':' + nsSrc203 ns.nsName = nsName204 ns.nsSrc = nsSrc205 ns.elementType = 'namespace'206 ns.toXml = new_instancemethod(dom.Namespace.toXml, ns)207 nss = Namespace()208 nss.ns = ns209 nss.nsName = nsName210 nss.nsSrc = nsSrc211 nss.name = nsName + ":" + nsSrc212 nss.parent = peach213 ns.parent = nss214 peach.append(nss)215 peach.namespaces.append(ns)216 setattr(peach.namespaces, nsName, ns)217 elif child_tag == 'PythonPath':218 # Add a search path219 p = self.HandlePythonPath(child, peach)220 peach.append(p)221 sys.path.append(p.name)222 elif child_tag == 'Defaults':223 self.HandleDefaults(child, peach)224 # one last check for unresolved macros225 for child in ePeach.iterdescendants():226 for k,v in list(child.items()):227 child.set(k, self.substituteConfigVariables(v, final=True))228 # Pass 2 -- Import229 for child in ePeach.iterchildren():230 child_tag = split_ns(child.tag)[1]231 if child_tag == 'Import':232 # Import module233 if child.get('import') is None:234 raise PeachException("Import element did not have import attribute!")235 importStr = self._getAttribute(child, 'import')236 if child.get('from') is not None:237 fromStr = self._getAttribute(child, 'from')238 if importStr == "*":239 module = __import__(PeachStr(fromStr), globals(), locals(), [PeachStr(importStr)], -1)240 try:241 # If we are a module with other modules in us then we have an __all__242 for item in module.__all__:243 globals()["PeachXml_" + item] = getattr(module, item)244 except:245 # Else we just have some classes in us with no __all__246 for item in self.GetClassesInModule(module):247 globals()["PeachXml_" + item] = getattr(module, item)248 else:249 module = __import__(PeachStr(fromStr), globals(), locals(), [PeachStr(importStr)], -1)250 for item in importStr.split(','):251 item = item.strip()252 globals()["PeachXml_" + item] = getattr(module, item)253 else:254 globals()["PeachXml_" + importStr] = __import__(PeachStr(importStr), globals(), locals(), [], -1)255 Holder.globals = globals()256 Holder.locals = locals()257 i = Element()258 i.elementType = 'import'259 i.importStr = self._getAttribute(child, 'import')260 i.fromStr = self._getAttribute(child, 'from')261 peach.append(i)262 # Pass 3 -- Template263 for child in ePeach.iterchildren():264 child_tag = split_ns(child.tag)[1]265 if child_tag == "Python":266 code = self._getAttribute(child, "code")267 if code is not None:268 exec(code)269 elif child_tag == 'Analyzer':270 self.HandleAnalyzerTopLevel(child, peach)271 elif child_tag == 'DataModel' or child_tag == 'Template':272 # do something273 template = self.HandleTemplate(child, peach)274 #template.node = child275 peach.append(template)276 peach.templates.append(template)277 setattr(peach.templates, template.name, template)278 # Pass 4 -- Data, Agent279 for child in ePeach.iterchildren():280 child_tag = split_ns(child.tag)[1]281 if child_tag == 'Data':282 # do data283 data = self.HandleData(child, peach)284 #data.node = child285 peach.append(data)286 peach.data.append(data)287 setattr(peach.data, data.name, data)288 elif child_tag == 'Agent':289 agent = self.HandleAgent(child, None)290 #agent.node = child291 peach.append(agent)292 peach.agents.append(agent)293 setattr(peach.agents, agent.name, agent)294 elif child_tag == 'StateModel' or child_tag == 'StateMachine':295 stateMachine = self.HandleStateMachine(child, peach)296 #stateMachine.node = child297 peach.append(stateMachine)298 elif child_tag == 'Mutators':299 if self._getBooleanAttribute(child, "enabled"):300 mutators = self.HandleMutators(child, peach)301 peach.mutators = mutators302 # Pass 5 -- Tests303 for child in ePeach.iterchildren():304 child_tag = split_ns(child.tag)[1]305 if child_tag == 'Test':306 tests = self.HandleTest(child, None)307 #tests.node = child308 peach.append(tests)309 peach.tests.append(tests)310 setattr(peach.tests, tests.name, tests)311 elif child_tag == 'Run':312 run = self.HandleRun(child, None)313 #run.node = child314 peach.append(run)315 peach.runs.append(run)316 setattr(peach.runs, run.name, run)317 # Pass 6 -- Analyzers318 # Simce analyzers can modify the DOM we need to make our list319 # of objects we will look at first!320 objs = []321 for child in peach.getElementsByType(Blob):322 if child.analyzer is not None and child.defaultValue is not None and child not in objs:323 objs.append(child)324 for child in peach.getElementsByType(String):325 if child.analyzer is not None and child.defaultValue is not None and child not in objs:326 objs.append(child)327 for child in objs:328 try:329 analyzer = eval("%s()" % child.analyzer)330 except:331 analyzer = eval("PeachXml_" + "%s()" % child.analyzer)332 analyzer.asDataElement(child, {}, child.defaultValue)333 # We suck, so fix this up334 peach._FixParents()335 peach.verifyDomMap()336 #peach.printDomMap()337 return peach338 def StripComments(self, node):339 i = 0340 while i < len(node):341 if not etree.iselement(node[i]):342 del node[i] # may not preserve text, don't care343 else:344 self.StripComments(node[i])345 i += 1346 def StripText(self, node):347 node.text = node.tail = None348 for desc in node.iterdescendants():349 desc.text = desc.tail = None350 def GetRef(self, str, parent=None, childAttr='templates'):351 """352 Get the object indicated by ref. Currently the object must have353 been defined prior to this point in the XML354 """355 #print "GetRef(%s) -- Starting" % str356 origStr = str357 baseObj = self.context358 hasNamespace = False359 isTopName = True360 found = False361 # Parse out a namespace362 if str.find(":") > -1:363 ns, tmp = str.split(':')364 str = tmp365 #print "GetRef(%s): Found namepsace: %s" % (str, ns)366 # Check for namespace367 if hasattr(self.context.namespaces, ns):368 baseObj = getattr(self.context.namespaces, ns)369 else:370 #print self371 raise PeachException("Unable to locate namespace: " + origStr)372 hasNamespace = True373 for name in str.split('.'):374 #print "GetRef(%s): Looking for part %s" % (str, name)375 found = False376 if not hasNamespace and isTopName and parent is not None:377 # check parent, walk up from current parent to top378 # level parent checking at each level.379 while parent is not None and not found:380 #print "GetRef(%s): Parent.name: %s" % (name, parent.name)381 if hasattr(parent, 'name') and parent.name == name:382 baseObj = parent383 found = True384 elif hasattr(parent, name):385 baseObj = getattr(parent, name)386 found = True387 elif hasattr(parent.children, name):388 baseObj = getattr(parent.children, name)389 found = True390 elif hasattr(parent, childAttr) and hasattr(getattr(parent, childAttr), name):391 baseObj = getattr(getattr(parent, childAttr), name)392 found = True393 else:394 parent = parent.parent395 # check base obj396 elif hasattr(baseObj, name):397 baseObj = getattr(baseObj, name)398 found = True399 # check childAttr400 elif hasattr(baseObj, childAttr):401 obj = getattr(baseObj, childAttr)402 if hasattr(obj, name):403 baseObj = getattr(obj, name)404 found = True405 else:406 raise PeachException("Could not resolve ref %s" % origStr)407 # check childAttr408 if found == False and hasattr(baseObj, childAttr):409 obj = getattr(baseObj, childAttr)410 if hasattr(obj, name):411 baseObj = getattr(obj, name)412 found = True413 # check across namespaces if we can't find it in ours414 if isTopName and found == False:415 for child in baseObj:416 if child.elementType != 'namespace':417 continue418 #print "GetRef(%s): CHecking namepsace: %s" % (str, child.name)419 ret = self._SearchNamespaces(child, name, childAttr)420 if ret:421 #print "GetRef(%s) Found part %s in namespace" % (str, name)422 baseObj = ret423 found = True424 isTopName = False425 if not found:426 raise PeachException("Unable to resolve reference: %s" % origStr)427 return baseObj428 def _SearchNamespaces(self, obj, name, attr):429 """430 Used by GetRef to search across namespaces431 """432 #print "_SearchNamespaces(%s, %s)" % (obj.name, name)433 #print "dir(obj): ", dir(obj)434 # Namespaces are stuffed under this variable435 # if we have it we should be it :)436 if hasattr(obj, 'ns'):437 obj = obj.ns438 if hasattr(obj, name):439 return getattr(obj, name)440 elif hasattr(obj, attr) and hasattr(getattr(obj, attr), name):441 return getattr(getattr(obj, attr), name)442 for child in obj:443 if child.elementType != 'namespace':444 continue445 ret = self._SearchNamespaces(child, name, attr)446 if ret is not None:447 return ret448 return None449 def GetDataRef(self, str):450 """451 Get the data object indicated by ref. Currently the object must452 have been defined prior to this point in the XML.453 """454 origStr = str455 baseObj = self.context456 # Parse out a namespace457 if str.find(":") > -1:458 ns, tmp = str.split(':')459 str = tmp460 #print "GetRef(): Found namepsace:",ns461 # Check for namespace462 if hasattr(self.context.namespaces, ns):463 baseObj = getattr(self.context.namespaces, ns)464 else:465 raise PeachException("Unable to locate namespace")466 for name in str.split('.'):467 # check base obj468 if hasattr(baseObj, name):469 baseObj = getattr(baseObj, name)470 # check templates471 elif hasattr(baseObj, 'data') and hasattr(baseObj.data, name):472 baseObj = getattr(baseObj.data, name)473 else:474 raise PeachException("Could not resolve ref '%s'" % origStr)475 return baseObj476 _regsHex = (477 re.compile(r"^([,\s]*\\x([a-zA-Z0-9]{2})[,\s]*)"),478 re.compile(r"^([,\s]*%([a-zA-Z0-9]{2})[,\s]*)"),479 re.compile(r"^([,\s]*0x([a-zA-Z0-9]{2})[,\s]*)"),480 re.compile(r"^([,\s]*x([a-zA-Z0-9]{2})[,\s]*)"),481 re.compile(r"^([,\s]*([a-zA-Z0-9]{2})[,\s]*)")482 )483 def GetValueFromNode(self, node):484 value = None485 type = 'string'486 if node.get('valueType') is not None:487 type = self._getAttribute(node, 'valueType')488 if not (type == 'literal' or type == 'hex'):489 type = 'string'490 if node.get('value') is not None:491 value = self._getAttribute(node, 'value')492 # Convert variouse forms of hex into a binary string493 if type == 'hex':494 if len(value) == 1:495 value = "0" + value496 ret = ''497 valueLen = len(value) + 1498 while valueLen > len(value):499 valueLen = len(value)500 for i in range(len(self._regsHex)):501 match = self._regsHex[i].search(value)502 if match is not None:503 while match is not None:504 ret += chr(int(match.group(2), 16))505 value = self._regsHex[i].sub('', value)506 match = self._regsHex[i].search(value)507 break508 return ret509 elif type == 'literal':510 return eval(value)511 if value is not None and (type == 'string' or node.get('valueType') is None):512 value = re.sub(r"([^\\])\\n", r"\1\n", value)513 value = re.sub(r"([^\\])\\r", r"\1\r", value)514 value = re.sub(r"([^\\])\\t", r"\1\t", value)515 value = re.sub(r"([^\\])\\n", r"\1\n", value)516 value = re.sub(r"([^\\])\\r", r"\1\r", value)517 value = re.sub(r"([^\\])\\t", r"\1\t", value)518 value = re.sub(r"^\\n", r"\n", value)519 value = re.sub(r"^\\r", r"\r", value)520 value = re.sub(r"^\\t", r"\t", value)521 value = re.sub(r"\\\\", r"\\", value)522 return value523 def GetValueFromNodeString(self, node):524 """525 This one is specific to <String> elements. We526 want to preserve unicode characters.527 """528 value = None529 type = 'string'530 if node.get('valueType') is not None:531 type = self._getAttribute(node, 'valueType')532 if not type in ['literal', 'hex', 'string']:533 raise PeachException("Error: [%s] has invalid valueType attribute." % node.getFullname())534 if node.get('value') is not None:535 value = node.get('value')536 # Convert variouse forms of hex into a binary string537 if type == 'hex':538 value = str(value)539 if len(value) == 1:540 value = "0" + value541 ret = ''542 valueLen = len(value) + 1543 while valueLen > len(value):544 valueLen = len(value)545 for i in range(len(self._regsHex)):546 match = self._regsHex[i].search(value)547 if match is not None:548 while match is not None:549 ret += chr(int(match.group(2), 16))550 value = self._regsHex[i].sub('', value)551 match = self._regsHex[i].search(value)552 break553 return ret554 elif type == 'literal':555 value = eval(value)556 if value is not None and type == 'string':557 value = re.sub(r"([^\\])\\n", r"\1\n", value)558 value = re.sub(r"([^\\])\\r", r"\1\r", value)559 value = re.sub(r"([^\\])\\t", r"\1\t", value)560 value = re.sub(r"([^\\])\\n", r"\1\n", value)561 value = re.sub(r"([^\\])\\r", r"\1\r", value)562 value = re.sub(r"([^\\])\\t", r"\1\t", value)563 value = re.sub(r"^\\n", r"\n", value)564 value = re.sub(r"^\\r", r"\r", value)565 value = re.sub(r"^\\t", r"\t", value)566 value = re.sub(r"\\\\", r"\\", value)567 return value568 def GetValueFromNodeNumber(self, node):569 value = None570 type = 'string'571 if node.get('valueType') is not None:572 type = self._getAttribute(node, 'valueType')573 if not type in ['literal', 'hex', 'string']:574 raise PeachException("Error: [%s] has invalid valueType attribute." % node.getFullname())575 if node.get('value') is not None:576 value = self._getAttribute(node, 'value')577 # Convert variouse forms of hex into a binary string578 if type == 'hex':579 if len(value) == 1:580 value = "0" + value581 ret = ''582 valueLen = len(value) + 1583 while valueLen > len(value):584 valueLen = len(value)585 for i in range(len(self._regsHex)):586 match = self._regsHex[i].search(value)587 if match is not None:588 while match is not None:589 ret += match.group(2)590 value = self._regsHex[i].sub('', value)591 match = self._regsHex[i].search(value)592 break593 return int(ret, 16)594 elif type == 'literal':595 value = eval(value)596 return value597 # Handlers for Template ###################################################598 def HandleTemplate(self, node, parent):599 """600 Parse an element named Template. Can handle actual601 Template elements and also reference Template elements.602 e.g.:603 <Template name="Xyz"> ... </Template>604 or605 <Template ref="Xyz" />606 """607 template = None608 # ref609 if node.get('ref') is not None:610 # We have a base template611 obj = self.GetRef(self._getAttribute(node, 'ref'))612 template = obj.copy(parent)613 template.ref = self._getAttribute(node, 'ref')614 template.parent = parent615 else:616 template = Template(self._getAttribute(node, 'name'))617 template.ref = None618 template.parent = parent619 # name620 if node.get('name') is not None:621 template.name = self._getAttribute(node, 'name')622 template.elementType = 'template'623 # mutable624 mutable = self._getAttribute(node, 'mutable')625 if mutable is None or len(mutable) == 0:626 template.isMutable = True627 elif mutable.lower() == 'true':628 template.isMutable = True629 elif mutable.lower() == 'false':630 template.isMutable = False631 else:632 raise PeachException(633 "Attribute 'mutable' has unexpected value [%s], only 'true' and 'false' are supported." % mutable)634 # pointer635 pointer = self._getAttribute(node, 'pointer')636 if pointer is None:637 pass638 elif pointer.lower() == 'true':639 template.isPointer = True640 elif pointer.lower() == 'false':641 template.isPointer = False642 else:643 raise PeachException(644 "Attribute 'pointer' has unexpected value [%s], only 'true' and 'false' are supported." % pointer)645 # pointerDepth646 if node.get("pointerDepth") is not None:647 template.pointerDepth = self._getAttribute(node, 'pointerDepth')648 # children649 self.HandleDataContainerChildren(node, template)650 # Switch any references to old name651 if node.get('ref') is not None:652 oldName = self._getAttribute(node, 'ref')653 for relation in template._genRelationsInDataModelFromHere():654 if relation.of == oldName:655 relation.of = template.name656 elif relation.From == oldName:657 relation.From = template.name658 #template.printDomMap()659 return template660 def HandleCommonTemplate(self, node, elem):661 """662 Handle the common children of data elements like String and Number.663 """664 elem.onArrayNext = self._getAttribute(node, "onArrayNext")665 for child in node:666 child_nodeName = split_ns(child.tag)[1]667 if child_nodeName == 'Relation':668 relation = self.HandleRelation(child, elem)669 elem.relations.append(relation)670 elif child_nodeName == 'Transformer':671 if elem.transformer is not None:672 raise PeachException("Error, data element [%s] already has a transformer." % elem.name)673 elem.transformer = self.HandleTransformer(child, elem)674 elif child_nodeName == 'Fixup':675 self.HandleFixup(child, elem)676 elif child_nodeName == 'Placement':677 self.HandlePlacement(child, elem)678 elif child_nodeName == 'Hint':679 self.HandleHint(child, elem)680 else:681 raise PeachException("Found unexpected child node '%s' in element '%s'." % (child_nodeName, elem.name))682 def HandleTransformer(self, node, parent):683 """684 Handle Transformer element685 """686 transformer = Transformer(parent)687 childTransformer = None688 params = []689 # class690 if node.get("class") is None:691 raise PeachException("Transformer element missing class attribute")692 generatorClass = self._getAttribute(node, "class")693 transformer.classStr = generatorClass694 # children695 for child in node.iterchildren():696 child_nodeName = split_ns(child.tag)[1]697 if child_nodeName == 'Transformer':698 if childTransformer is not None:699 raise PeachException("A transformer can only have one child transformer")700 childTransformer = self.HandleTransformer(child, transformer)701 continue702 if child_nodeName == 'Param':703 param = self.HandleParam(child, transformer)704 transformer.append(param)705 params.append([param.name, param.defaultValue])706 code = "PeachXml_" + generatorClass + '('707 isFirst = True708 for param in params:709 if not isFirst:710 code += ', '711 else:712 isFirst = False713 code += PeachStr(param[1])714 code += ')'715 trans = eval(code, globals(), locals())716 if childTransformer is not None:717 trans.addTransformer(childTransformer.transformer)718 transformer.transformer = trans719 if parent is not None:720 parent.transformer = transformer721 transformer.parent = parent722 #parent.append(transformer)723 return transformer724 def HandleDefaults(self, node, parent):725 """726 Handle data element defaults727 """728 # children729 for child in node.iterchildren():730 child_nodeName = split_ns(child.tag)[1]731 if child_nodeName == 'Blob':732 if child.get('valueType') is not None:733 Blob.defaultValueType = self._getAttribute(child, 'valueType')734 if Blob.defaultValueType not in ['string', 'literal', 'hex']:735 raise PeachException("Error, default value for Blob.valueType incorrect.")736 if child.get('lengthType') is not None:737 Blob.defaultLengthType = self._getAttribute(child, 'lengthType')738 if Blob.defaultLengthType not in ['string', 'literal', 'calc']:739 raise PeachException("Error, default value for Blob.lengthType incorrect.")740 elif child_nodeName == 'Flags':741 if child.get('endian') is not None:742 Flags.defaultEndian = self._getAttribute(child, 'endian')743 if Flags.defaultEndian not in ['little', 'big', 'network']:744 raise PeachException("Error, default value for Flags.endian incorrect.")745 elif child_nodeName == 'Number':746 if child.get('endian') is not None:747 Number.defaultEndian = self._getAttribute(child, 'endian')748 if Number.defaultEndian not in ['little', 'big', 'network']:749 raise PeachException("Error, default value for Number.endian incorrect.")750 if child.get('size') is not None:751 Number.defaultSize = int(self._getAttribute(child, 'size'))752 if Number.defaultSize not in Number._allowedSizes:753 raise PeachException("Error, default value for Number.size incorrect.")754 if child.get('signed') is not None:755 Number.defaultSigned = self._getAttribute(child, 'signed')756 if Number.defaultSigned not in ['true', 'false']:757 raise PeachException("Error, default value for Number.signed incorrect.")758 if Number.defaultSigned == 'true':759 Number.defaultSigned = True760 else:761 Number.defaultSigned = False762 if child.get('valueType') is not None:763 Number.defaultValueType = self._getAttribute(child, 'valueType')764 if Number.defaultValueType not in ['string', 'literal', 'hex']:765 raise PeachException("Error, default value for Number.valueType incorrect.")766 elif child_nodeName == 'String':767 if child.get('valueType') is not None:768 String.defaultValueType = self._getAttribute(child, 'valueType')769 if String.defaultValueType not in ['string', 'literal', 'hex']:770 raise PeachException("Error, default value for String.valueType incorrect.")771 if child.get('lengthType') is not None:772 String.defaultLengthType = self._getAttribute(child, 'lengthType')773 if String.defaultLengthType not in ['string', 'literal', 'calc']:774 raise PeachException("Error, default value for String.lengthType incorrect.")775 if child.get('padCharacter') is not None:776 String.defaultPadCharacter = child.get('padCharacter')777 if child.get('type') is not None:778 String.defaultType = self._getAttribute(child, 'type')779 if String.defaultType not in ['wchar', 'char', 'utf8']:780 raise PeachException("Error, default value for String.type incorrect.")781 if child.get('nullTerminated') is not None:782 String.defaultNullTerminated = self._getAttribute(child, 'nullTerminated')783 if String.defaultNullTerminated not in ['true', 'false']:784 raise PeachException("Error, default value for String.nullTerminated incorrect.")785 if String.defaultNullTerminated == 'true':786 String.defaultNullTerminated = True787 else:788 String.defaultNullTerminated = False789 def HandleFixup(self, node, parent):790 """791 Handle Fixup element792 """793 fixup = Fixup(parent)794 params = []795 # class796 if node.get("class") is None:797 raise PeachException("Fixup element missing class attribute")798 fixup.classStr = self._getAttribute(node, "class")799 # children800 for child in node.iterchildren():801 if split_ns(child.tag)[1] == 'Param':802 param = self.HandleParam(child, fixup)803 fixup.append(param)804 params.append([param.name, param.defaultValue])805 code = "PeachXml_" + fixup.classStr + '('806 isFirst = True807 for param in params:808 if not isFirst:809 code += ', '810 else:811 isFirst = False812 code += PeachStr(param[1])813 code += ')'814 fixup.fixup = eval(code, globals(), locals())815 if parent is not None:816 if parent.fixup is not None:817 raise PeachException("Error, data element [%s] already has a fixup." % parent.name)818 parent.fixup = fixup819 return fixup820 def HandlePlacement(self, node, parent):821 """822 Handle Placement element823 """824 placement = Placement(parent)825 placement.after = self._getAttribute(node, "after")826 placement.before = self._getAttribute(node, "before")827 if placement.after is None and placement.before is None:828 raise PeachException("Error: Placement element must have an 'after' or 'before' attribute.")829 if placement.after is not None and placement.before is not None:830 raise PeachException("Error: Placement can only have one of 'after' or 'before' but not both.")831 if parent is not None:832 if parent.placement is not None:833 raise PeachException("Error, data element [%s] already has a placement." % parent.name)834 #print "Setting placement on",parent.name835 parent.placement = placement836 #parent.append(placement)837 return placement838 def HandleRelation(self, node, elem):839 if node.get("type") is None:840 raise PeachException("Relation element does not have type attribute")841 type = self._getAttribute(node, "type")842 of = self._getAttribute(node, "of")843 From = self._getAttribute(node, "from")844 name = self._getAttribute(node, "name")845 when = self._getAttribute(node, "when")846 expressionGet = self._getAttribute(node, "expressionGet")847 expressionSet = self._getAttribute(node, "expressionSet")848 relative = self._getAttribute(node, "relative")849 if of is None and From is None and when is None:850 raise PeachException("Relation element does not have of, from, or when attribute.")851 if type not in ['size', 'count', 'index', 'when', 'offset']:852 raise PeachException("Unknown type value in Relation element")853 relation = Relation(name, elem)854 relation.of = of855 relation.From = From856 relation.type = type857 relation.when = when858 relation.expressionGet = expressionGet859 relation.expressionSet = expressionSet860 if self._getAttribute(node, "isOutputOnly") is not None and self._getAttribute(node, "isOutputOnly") in ["True",861 "true"]:862 relation.isOutputOnly = True863 if relative is not None:864 if relative.lower() in ["true", "1"]:865 relation.relative = True866 relation.relativeTo = self._getAttribute(node, "relativeTo")867 elif relative.lower() in ["false", "0"]:868 relation.relative = False869 relation.relativeTo = None870 else:871 raise PeachException("Error: Value of Relation relative attribute is not true or false.")872 return relation873 def HandleAnalyzerTopLevel(self, node, elem):874 if node.get("class") is None:875 raise PeachException("Analyzer element must have a 'class' attribute")876 # Locate any arguments877 args = {}878 for child in node.iterchildren():879 if split_ns(child.tag)[1] == 'Param' and child.get('name') is not None:880 args[self._getAttribute(child, 'name')] = self._getAttribute(child, 'value')881 cls = self._getAttribute(node, "class")882 try:883 obj = eval("%s()" % cls)884 except:885 raise PeachException("Error creating analyzer '%s': %s" % (obj, repr(sys.exc_info())))886 if not obj.supportTopLevel:887 raise PeachException("Analyzer '%s' does not support use as top-level element" % cls)888 obj.asTopLevel(self.context, args)889 def HandleCommonDataElementAttributes(self, node, element):890 """891 Handle attributes common to all DataElements such as:892 - minOccurs, maxOccurs893 - mutable894 - isStatic895 - constraint896 - pointer897 - pointerDepth898 - token899 """900 # min/maxOccurs901 self._HandleOccurs(node, element)902 # isStatic/token903 isStatic = self._getAttribute(node, 'isStatic')904 if isStatic is None:905 isStatic = self._getAttribute(node, 'token')906 if isStatic is None or len(isStatic) == 0:907 element.isStatic = False908 elif isStatic.lower() == 'true':909 element.isStatic = True910 elif isStatic.lower() == 'false':911 element.isStatic = False912 else:913 if node.get("isStatic") is not None:914 raise PeachException(915 "Attribute 'isStatic' has unexpected value [%s], only 'true' and 'false' are supported." % isStatic)916 else:917 raise PeachException(918 "Attribute 'token' has unexpected value [%s], only 'true' and 'false' are supported." % isStatic)919 # mutable920 mutable = self._getAttribute(node, 'mutable')921 if mutable is None or len(mutable) == 0:922 element.isMutable = True923 elif mutable.lower() == 'true':924 element.isMutable = True925 elif mutable.lower() == 'false':926 element.isMutable = False927 else:928 raise PeachException(929 "Attribute 'mutable' has unexpected value [%s], only 'true' and 'false' are supported." % mutable)930 # pointer931 pointer = self._getAttribute(node, 'pointer')932 if pointer is None:933 pass934 elif pointer.lower() == 'true':935 element.isPointer = True936 elif pointer.lower() == 'false':937 element.isPointer = False938 else:939 raise PeachException(940 "Attribute 'pointer' has unexpected value [%s], only 'true' and 'false' are supported." % pointer)941 # pointerDepth942 if node.get("pointerDepth") is not None:943 element.pointerDepth = self._getAttribute(node, 'pointerDepth')944 # constraint945 element.constraint = self._getAttribute(node, "constraint")946 def _HandleOccurs(self, node, element):947 """948 Grab min, max, and generated Occurs attributes949 """950 if node.get('generatedOccurs') is not None:951 element.generatedOccurs = self._getAttribute(node, 'generatedOccurs')952 else:953 element.generatedOccurs = 10954 occurs = self._getAttribute(node, 'occurs')955 minOccurs = self._getAttribute(node, 'minOccurs')956 maxOccurs = self._getAttribute(node, 'maxOccurs')957 if minOccurs is None:958 minOccurs = 1959 else:960 minOccurs = eval(minOccurs)961 if maxOccurs is None:962 maxOccurs = 1963 else:964 maxOccurs = eval(maxOccurs)965 if minOccurs is not None and maxOccurs is not None:966 element.minOccurs = int(minOccurs)967 element.maxOccurs = int(maxOccurs)968 elif minOccurs is not None and maxOccurs is None:969 element.minOccurs = int(minOccurs)970 element.maxOccurs = 1024971 elif maxOccurs is not None and minOccurs is None:972 element.minOccurs = 0973 element.maxOccurs = int(maxOccurs)974 else:975 element.minOccurs = 1976 element.maxOccurs = 1977 if occurs is not None:978 element.occurs = element.minOccurs = element.maxOccurs = int(occurs)979 def HandleBlock(self, node, parent):980 # name981 if node.get('name') is not None:982 name = self._getAttribute(node, 'name')983 else:984 name = None985 # ref986 if node.get('ref') is not None:987 oldName = self._getAttribute(node, "ref")988 if name is None or len(name) == 0:989 name = Element.getUniqueName()990 # We have a base template991 obj = self.GetRef(self._getAttribute(node, 'ref'), parent)992 block = obj.copy(parent)993 block.name = name994 block.parent = parent995 block.ref = self._getAttribute(node, 'ref')996 # Block may not be a block!997 if getattr(block, 'toXml', None) is None:998 block.toXml = new_instancemethod(dom.Block.toXml, block)999 block.elementType = 'block'1000 else:1001 block = dom.Block(name, parent)1002 block.ref = None1003 #block.node = node1004 # length (in bytes)1005 if node.get('lengthType') is not None and self._getAttribute(node, 'lengthType') == 'calc':1006 block.lengthType = self._getAttribute(node, 'lengthType')1007 block.lengthCalc = self._getAttribute(node, 'length')1008 block.length = -11009 elif node.get('length') is not None:1010 length = self._getAttribute(node, 'length')1011 if length is not None and len(length) != 0:1012 block.length = int(length)1013 else:1014 block.length = None1015 # alignment1016 try:1017 alignment = self._getAttribute(node, 'alignment')1018 if len(alignment) == 0:1019 alignment = None1020 except:1021 alignment = None1022 if alignment is not None:1023 block.isAligned = True1024 block.alignment = int(alignment) ** 21025 # common attributes1026 self.HandleCommonDataElementAttributes(node, block)1027 # children1028 self.HandleDataContainerChildren(node, block)1029 # Switch any references to old name1030 if node.get('ref') is not None:1031 for relation in block._genRelationsInDataModelFromHere():1032 if relation.of == oldName:1033 relation.of = name1034 elif relation.From == oldName:1035 relation.From = name1036 # Add to parent1037 parent.append(block)1038 return block1039 def HandleDataContainerChildren(self, node, parent, errorOnUnknown=True):1040 """1041 Handle parsing conatiner children. This method1042 will handle children of DataElement types for1043 containers like Block, Choice, and Template.1044 Can be used by Custom types to create Custom container1045 types.1046 @type node: XML Element1047 @param node: Current XML Node being handled1048 @type parent: ElementWithChildren1049 @param parent: Parent of this DataElement1050 @type errorOnUnknown: Boolean1051 @param errorOnUnknonw: Should we throw an error on unexpected child node (default True)1052 """1053 # children1054 for child in node.iterchildren():1055 name = self._getAttribute(child, 'name')1056 if name is not None and '.' in name:1057 # Replace a deep node, can only happen if we1058 # have a ref on us.1059 if node.get('ref') is None:1060 raise PeachException(1061 "Error, periods (.) are not allowed in element names unless overrideing deep elements when a parent reference (ref). Name: [%s]" % name)1062 # Okay, lets locate the real parent.1063 obj = parent1064 for part in name.split('.')[:-1]:1065 if part not in obj:1066 raise PeachException(1067 "Error, unable to resolve [%s] in deep parent of [%s] override." % (part, name))1068 obj = obj[part]1069 if obj is None:1070 raise PeachException("Error, unable to resolve deep parent of [%s] override." % name)1071 # Remove periods from name1072 child.set('name', name.split('.')[-1])1073 # Handle child with new parent.1074 self._HandleDataContainerChildren(node, child, obj, errorOnUnknown)1075 else:1076 self._HandleDataContainerChildren(node, child, parent, errorOnUnknown)1077 def _HandleDataContainerChildren(self, node, child, parent, errorOnUnknown=True):1078 node_nodeName = split_ns(node.tag)[1]1079 child_nodeName = split_ns(child.tag)[1]1080 if child_nodeName == 'Block':1081 self.HandleBlock(child, parent)1082 elif child_nodeName == 'String':1083 self.HandleString(child, parent)1084 elif child_nodeName == 'Number':1085 self.HandleNumber(child, parent)1086 elif child_nodeName == 'Flags':1087 self.HandleFlags(child, parent)1088 elif child_nodeName == 'Flag':1089 self.HandleFlag(child, parent)1090 elif child_nodeName == 'Blob':1091 self.HandleBlob(child, parent)1092 elif child_nodeName == 'Choice':1093 self.HandleChoice(child, parent)1094 elif child_nodeName == 'Transformer':1095 parent.transformer = self.HandleTransformer(child, parent)1096 elif child_nodeName == 'Relation':1097 relation = self.HandleRelation(child, parent)1098 parent.relations.append(relation)1099 elif child_nodeName == 'Fixup':1100 self.HandleFixup(child, parent)1101 elif child_nodeName == 'Placement':1102 self.HandlePlacement(child, parent)1103 elif child_nodeName == 'Hint':1104 self.HandleHint(child, parent)1105 elif child_nodeName == 'Seek':1106 self.HandleSeek(child, parent)1107 elif child_nodeName == 'Custom':1108 self.HandleCustom(child, parent)1109 elif child_nodeName == 'Asn1':1110 self.HandleAsn1(child, parent)1111 elif child_nodeName == 'XmlElement':1112 # special XmlElement reference1113 if child.get('ref') is not None:1114 # This is our special case, if we ref we suck the children1115 # of the ref into our selves. This is tricky!1116 # get and copy our ref1117 obj = self.GetRef(self._getAttribute(child, 'ref'), parent.parent)1118 newobj = obj.copy(parent)1119 newobj.parent = None1120 # first verify all children are XmlElement or XmlAttribute1121 for subchild in newobj:1122 if not isinstance(subchild, XmlElement) and not isinstance(subchild, XmlAttribute):1123 raise PeachException(1124 "Error, special XmlElement ref case, reference must only have Xml elements!! (%s,%s,%s)" % (1125 subchild.parent.name, subchild.name, subchild))1126 # now move over children1127 for subchild in newobj:1128 parent.append(subchild)1129 # remove replaced element1130 if self._getAttribute(child, 'name') in parent:1131 del parent[self._getAttribute(child, 'name')]1132 else:1133 self.HandleXmlElement(child, parent)1134 elif child_nodeName == 'XmlAttribute':1135 self.HandleXmlAttribute(child, parent)1136 elif errorOnUnknown:1137 raise PeachException(1138 PeachStr("found unexpected node [%s] in Element: %s" % (child_nodeName, node_nodeName)))1139 def HandleMutators(self, node, parent):1140 # name1141 name = self._getAttribute(node, 'name')1142 mutators = dom.Mutators(name, parent)1143 # children1144 for child in node.iterchildren():1145 child_nodeName = split_ns(child.tag)[1]1146 if child_nodeName != 'Mutator':1147 raise PeachException(PeachStr("Found unexpected node in Mutators element: %s" % child_nodeName))1148 if child.get('class') is None:1149 raise PeachException("Mutator element does not have required class attribute")1150 mutator = Mutator(self._getAttribute(child, 'class'), mutators)1151 mutators.append(mutator)1152 parent.append(mutators)1153 return mutators1154 def HandleChoice(self, node, parent):1155 # name1156 name = self._getAttribute(node, 'name')1157 # ref1158 if node.get('ref') is not None:1159 if name is None or len(name) == 0:1160 name = Element.getUniqueName()1161 # We have a base template1162 obj = self.GetRef(self._getAttribute(node, 'ref'), parent)1163 #print "About to deep copy: ", obj, " for ref: ", self._getAttribute(node, 'ref')1164 block = obj.copy(parent)1165 block.name = name1166 block.parent = parent1167 block.ref = self._getAttribute(node, 'ref')1168 else:1169 block = Choice(name, parent)1170 block.ref = None1171 block.elementType = 'choice'1172 # length (in bytes)1173 if self._getAttribute(node, 'lengthType') == 'calc':1174 block.lengthType = self._getAttribute(node, 'lengthType')1175 block.lengthCalc = self._getAttribute(node, 'length')1176 block.length = -11177 elif node.get('length') is not None:1178 length = self._getAttribute(node, 'length')1179 if length is not None and len(length) != 0:1180 block.length = int(length)1181 else:1182 block.length = None1183 # common attributes1184 self.HandleCommonDataElementAttributes(node, block)1185 # children1186 self.HandleDataContainerChildren(node, block)1187 parent.append(block)1188 return block1189 def HandleAsn1(self, node, parent):1190 # name1191 name = self._getAttribute(node, 'name')1192 # ref1193 if node.get('ref') is not None:1194 raise PeachException("Asn1 element does not yet support ref!")1195 #1196 #if name == None or len(name) == 0:1197 # name = Element.getUniqueName()1198 #1199 ## We have a base template1200 #obj = self.GetRef( self._getAttribute(node, 'ref'), parent )1201 #1202 ##print "About to deep copy: ", obj, " for ref: ", self._getAttribute(node, 'ref')1203 #1204 #block = obj.copy(parent)1205 #block.name = name1206 #block.parent = parent1207 #block.ref = self._getAttribute(node, 'ref')1208 else:1209 block = Asn1Type(name, parent)1210 block.ref = None1211 # encode type1212 if node.get("encode"):1213 block.encodeType = node.get("encode")1214 # asn1Type1215 if node.get("type") is None:1216 raise PeachException("Error, all Asn1 elements must have 'type' attribute.")1217 block.asn1Type = node.get("type")1218 # Tag Stuff1219 if node.get("tagNumber") is not None:1220 try:1221 block.tagClass = Asn1Type.ASN1_TAG_CLASS_MAP[self._getAttribute(node, "tagClass").lower()]1222 block.tagFormat = Asn1Type.ASN1_TAG_TYPE_MAP[self._getAttribute(node, "tagFormat").lower()]1223 block.tagCategory = self._getAttribute(node, "tagCategory").lower()1224 block.tagNumber = int(self._getAttribute(node, "tagNumber"))1225 except:1226 raise PeachException(1227 "Error, When using tags you must specify 'tagClass', 'tagFormat', 'tagCategory', and 'tagNumber'.")1228 # common attributes1229 self.HandleCommonDataElementAttributes(node, block)1230 # children1231 self.HandleDataContainerChildren(node, block)1232 parent.append(block)1233 return block1234 def HandleXmlElement(self, node, parent):1235 # name1236 name = self._getAttribute(node, 'name')1237 block = XmlElement(name, parent)1238 # elementName1239 block.elementName = self._getAttribute(node, "elementName")1240 if block.elementName is None:1241 raise PeachException("Error: XmlElement without elementName attribute.")1242 # ns1243 block.xmlNamespace = self._getAttribute(node, "ns")1244 # length (in bytes)1245 if self._getAttribute(node, 'lengthType') == 'calc':1246 block.lengthType = self._getAttribute(node, 'lengthType')1247 block.lengthCalc = self._getAttribute(node, 'length')1248 block.length = -11249 elif node.get('length') is not None:1250 length = self._getAttribute(node, 'length')1251 if length is not None and len(length) != 0:1252 block.length = int(length)1253 else:1254 block.length = None1255 # common attributes1256 self.HandleCommonDataElementAttributes(node, block)1257 # children1258 self.HandleDataContainerChildren(node, block)1259 parent.append(block)1260 return block1261 def HandleXmlAttribute(self, node, parent):1262 # name1263 name = self._getAttribute(node, 'name')1264 block = XmlAttribute(name, parent)1265 # elementName1266 block.attributeName = self._getAttribute(node, "attributeName")1267 # ns1268 block.xmlNamespace = self._getAttribute(node, "ns")1269 # length (in bytes)1270 if self._getAttribute(node, 'lengthType') == 'calc':1271 block.lengthType = self._getAttribute(node, 'lengthType')1272 block.lengthCalc = self._getAttribute(node, 'length')1273 block.length = -11274 elif node.get('length') is not None:1275 length = self._getAttribute(node, 'length')1276 if length is not None and len(length) != 0:1277 block.length = int(length)1278 else:1279 block.length = None1280 # common attributes1281 self.HandleCommonDataElementAttributes(node, block)1282 # children1283 self.HandleDataContainerChildren(node, block)1284 parent.append(block)1285 return block1286 def _getAttribute(self, node, name):1287 attr = node.get(name)1288 if attr is None:1289 return None1290 return PeachStr(attr)1291 def _getValueType(self, node):1292 valueType = self._getAttribute(node, 'valueType')1293 if valueType is None:1294 return 'string'1295 return valueType1296 def HandleString(self, node, parent):1297 # name1298 name = self._getAttribute(node, 'name')1299 string = String(name, parent)1300 # value1301 string.defaultValue = self.GetValueFromNodeString(node)1302 string.valueType = self._getValueType(node)1303 string.defaultValue = self._HandleValueTypeString(string.defaultValue, string.valueType)1304 # tokens1305 string.tokens = self._getAttribute(node, 'tokens')1306 # padCharacter1307 if node.get('padCharacter') is not None:1308 val = node.get('padCharacter')1309 val = val.replace("'", "\\'")1310 string.padCharacter = eval("u'''" + val + "'''")1311 # type1312 if node.get('type') is not None:1313 type = self._getAttribute(node, 'type')1314 if type is None or len(type) == 0:1315 string.type = 'char'1316 elif not (type in ['char', 'wchar', 'utf8', 'utf-8', 'utf-16le', 'utf-16be']):1317 raise PeachException("Unknown type of String: %s" % type)1318 else:1319 string.type = type1320 # nullTerminated (optional)1321 if node.get('nullTerminated') is not None:1322 nullTerminated = self._getAttribute(node, 'nullTerminated')1323 if nullTerminated is None or len(nullTerminated) == 0:1324 nullTerminated = 'false'1325 if nullTerminated.lower() == 'true':1326 string.nullTerminated = True1327 elif nullTerminated.lower() == 'false':1328 string.nullTerminated = False1329 else:1330 raise PeachException("nullTerminated should be true or false")1331 # length (bytes)1332 if self._getAttribute(node, 'lengthType') == 'calc':1333 string.lengthType = self._getAttribute(node, 'lengthType')1334 string.lengthCalc = self._getAttribute(node, 'length')1335 string.length = -11336 elif node.get('length') is not None:1337 length = self._getAttribute(node, 'length')1338 if length is None or len(length) == 0:1339 length = None1340 try:1341 if length is not None:1342 string.length = int(length)1343 else:1344 string.length = None1345 except:1346 raise PeachException("length must be a number or missing %s" % length)1347 # Analyzer1348 string.analyzer = self._getAttribute(node, 'analyzer')1349 # common attributes1350 self.HandleCommonDataElementAttributes(node, string)1351 # Handle any common children1352 self.HandleCommonTemplate(node, string)1353 parent.append(string)1354 return string1355 def HandleNumber(self, node, parent):1356 # name1357 name = self._getAttribute(node, 'name')1358 number = Number(name, parent)1359 # value1360 number.defaultValue = PeachStr(self.GetValueFromNodeNumber(node))1361 number.valueType = self._getValueType(node)1362 if number.defaultValue is not None:1363 try:1364 number.defaultValue = int(number.defaultValue)1365 except:1366 raise PeachException("Error: The default value for <Number> elements must be an integer.")1367 # size (bits)1368 if node.get('size') is not None:1369 size = self._getAttribute(node, 'size')1370 if size is None:1371 raise PeachException(1372 "Number element %s is missing the 'size' attribute which is required." % number.name)1373 number.size = int(size)1374 if not number.size in number._allowedSizes:1375 raise PeachException("invalid size")1376 # endian (optional)1377 if node.get('endian') is not None:1378 number.endian = self._getAttribute(node, 'endian')1379 if number.endian == 'network':1380 number.endian = 'big'1381 if number.endian != 'little' and number.endian != 'big':1382 raise PeachException("invalid endian %s" % number.endian)1383 # signed (optional)1384 if node.get('signed') is not None:1385 signed = self._getAttribute(node, 'signed')1386 if signed is None or len(signed) == 0:1387 signed = Number.defaultSigned1388 if signed.lower() == 'true':1389 number.signed = True1390 elif signed.lower() == 'false':1391 number.signed = False1392 else:1393 raise PeachException("signed must be true or false")1394 # common attributes1395 self.HandleCommonDataElementAttributes(node, number)1396 # Handle any common children1397 self.HandleCommonTemplate(node, number)1398 parent.append(number)1399 return number1400 def HandleFlags(self, node, parent):1401 name = self._getAttribute(node, 'name')1402 flags = dom.Flags(name, parent)1403 #flags.node = node1404 # length (in bits)1405 length = self._getAttribute(node, 'size')1406 flags.length = int(length)1407 if flags.length % 2 != 0:1408 raise PeachException("length must be multiple of 2")1409 if flags.length not in [8, 16, 24, 32, 64]:1410 raise PeachException("Flags size must be one of 8, 16, 24, 32, or 64.")1411 # endian1412 if node.get('endian') is not None:1413 flags.endian = self._getAttribute(node, 'endian')1414 if not ( flags.endian == 'little' or flags.endian == 'big' ):1415 raise PeachException("Invalid endian type on Flags element")1416 # rightToLeft1417 if node.get('rightToLeft') is not None:1418 if self._getAttribute(node, 'rightToLeft').lower() == "true":1419 flags.rightToLeft = True1420 elif self._getAttribute(node, 'rightToLeft').lower() == "false":1421 flags.rightToLeft = False1422 else:1423 raise PeachException("Flags attribute rightToLeft must be 'true' or 'false'.")1424 # padding1425 if node.get('padding') is not None:1426 if self._getAttribute(node, 'padding').lower() == "true":1427 flags.padding = True1428 elif self._getAttribute(node, 'padding').lower() == "false":1429 flags.padding = False1430 else:1431 raise PeachException("Flags attribute padding must be 'true' or 'false'.")1432 # constraint1433 flags.constraint = self._getAttribute(node, "constraint")1434 # children1435 for child in node.iterchildren():1436 child_nodeName = split_ns(child.tag)[1]1437 if child_nodeName == 'Flag':1438 childName = self._getAttribute(child, 'name')1439 if childName is not None:1440 if childName in flags:1441 raise PeachException("Error, found duplicate Flag name in Flags set [%s]" % flags.name)1442 self.HandleFlag(child, flags)1443 elif child_nodeName == 'Relation':1444 self.HandleRelation(child, flags)1445 else:1446 raise PeachException(PeachStr("found unexpected node in Flags: %s" % child_nodeName))1447 parent.append(flags)1448 return flags1449 def HandleFlag(self, node, parent):1450 name = self._getAttribute(node, 'name')1451 flag = Flag(name, parent)1452 #flag.node = node1453 # value1454 flag.defaultValue = PeachStr(self.GetValueFromNode(node))1455 flag.valueType = self._getValueType(node)1456 # position (in bits)1457 position = self._getAttribute(node, 'position')1458 flag.position = int(position)1459 # length (in bits)1460 length = self._getAttribute(node, 'size')1461 flag.length = int(length)1462 if flag.position > parent.length:1463 raise PeachException("Invalid position, parent not big enough")1464 if flag.position + flag.length > parent.length:1465 raise PeachException("Invalid length, parent not big enough")1466 # Handle any common children1467 self.HandleCommonTemplate(node, flag)1468 # Handle common data elements attributes1469 self.HandleCommonDataElementAttributes(node, flag)1470 # rest1471 parent.append(flag)1472 return flag1473 def HandleBlob(self, node, parent):1474 name = self._getAttribute(node, 'name')1475 blob = Blob(name, parent)1476 # value1477 blob.defaultValue = PeachStr(self.GetValueFromNode(node))1478 blob.valueType = self._getValueType(node)1479 # length (in bytes)1480 if self._getAttribute(node, 'lengthType') == 'calc':1481 blob.lengthType = self._getAttribute(node, 'lengthType')1482 blob.lengthCalc = self._getAttribute(node, 'length')1483 blob.length = -11484 elif node.get('length') is not None:1485 length = self._getAttribute(node, 'length')1486 if length is not None and len(length) != 0:1487 blob.length = int(length)1488 else:1489 blob.length = None1490 # padValue1491 if node.get('padValue') is not None:1492 blob.padValue = self._getAttribute(node, 'padValue')1493 else:1494 blob.padValue = "\0"1495 # Analyzer1496 blob.analyzer = self._getAttribute(node, 'analyzer')1497 # common attributes1498 self.HandleCommonDataElementAttributes(node, blob)1499 # Handle any common children1500 self.HandleCommonTemplate(node, blob)1501 parent.append(blob)1502 return blob1503 def HandleCustom(self, node, parent):1504 name = self._getAttribute(node, 'name')1505 cls = self._getAttribute(node, 'class')1506 code = "PeachXml_%s(name, parent)" % cls1507 custom = eval(code, globals(), locals())1508 #custom.node = node1509 # value1510 custom.defaultValue = PeachStr(self.GetValueFromNode(node))1511 custom.valueType = self._getValueType(node)1512 # Hex handled elsewere.1513 if custom.valueType == 'literal':1514 custom.defaultValue = PeachStr(eval(custom.defaultValue))1515 # common attributes1516 self.HandleCommonDataElementAttributes(node, custom)1517 # Handle any common children1518 self.HandleCommonTemplate(node, custom)1519 # constraint1520 custom.constraint = self._getAttribute(node, "constraint")1521 # Custom parsing1522 custom.handleParsing(node)1523 # Done1524 parent.append(custom)1525 return custom1526 def HandleSeek(self, node, parent):1527 """1528 Parse a <Seek> element, part of a data model.1529 """1530 seek = Seek(None, parent)1531 #seek.node = node1532 seek.expression = self._getAttribute(node, 'expression')1533 seek.position = self._getAttribute(node, 'position')1534 seek.relative = self._getAttribute(node, 'relative')1535 if seek.relative is not None:1536 seek.relative = int(seek.relative)1537 if seek.position is not None:1538 seek.position = int(seek.position)1539 if seek.expression is None and seek.position is None and seek.relative is None:1540 raise PeachException("Error: <Seek> element must have an expression, position, or relative attribute.")1541 parent.append(seek)1542 return seek1543 def HandleData(self, node, parent):1544 # attribute: name1545 name = self._getAttribute(node, 'name')1546 # attribute: ref1547 if node.get('ref') is not None:1548 if name is None or not len(name):1549 name = Element.getUniqueName()1550 data = self.GetDataRef(self._getAttribute(node, 'ref')).copy(parent)1551 data.name = name1552 else:1553 data = Data(name)1554 if not isinstance(parent, Action) and (name is None or not len(name)):1555 raise PeachException("<Data> must have a name attribute!")1556 data.elementType = 'data'1557 # attribute: maxFileSize1558 if node.get('maxFileSize') is not None:1559 data.maxFileSize = int(self._getAttribute(node, 'maxFileSize'))1560 # attribute: fileName1561 if node.get('fileName') is not None:1562 data.fileName = self._getAttribute(node, 'fileName')1563 if data.fileName.find('*') != -1:1564 data.fileGlob = data.fileName1565 for fpath in glob.glob(data.fileGlob):1566 if data.is_valid(fpath):1567 data.fileName = fpath1568 data.multipleFiles = True1569 elif os.path.isdir(data.fileName):1570 data.folderName = data.fileName1571 for fname in os.listdir(data.folderName):1572 fpath = os.path.join(data.folderName, fname)1573 if data.is_valid(fpath):1574 data.fileName = fpath1575 data.multipleFiles = True1576 if not os.path.isfile(data.fileName):1577 raise PeachException("No sample data found matching requirements of <Data> element.")1578 # attribute: recurse1579 if node.get('recurse') is not None:1580 data.recurse = bool(self._getAttribute(node, 'recurse'))1581 # attribute: switchCount1582 if node.get('switchCount') is not None:1583 data.switchCount = int(self._getAttribute(node, 'switchCount'))1584 else:1585 data.switchCount = None1586 # attribute: expression1587 if node.get('expression') is not None:1588 if data.fileName is not None:1589 raise PeachException("<Data> can not have both a fileName and expression attribute.")1590 data.expression = self._getAttribute(node, 'expression')1591 # children1592 for child in node.iterchildren():1593 child_nodeName = split_ns(child.tag)[1]1594 if child_nodeName == 'Field':1595 if data.fileName is not None or data.expression is not None:1596 raise PeachException("<Data> can not have a fileName or expression attribute along with Field "1597 "child elements.")1598 self.HandleField(child, data)1599 else:1600 raise PeachException("Found unexpected node inside <Data>: %s" % child_nodeName)1601 return data1602 def HandleField(self, node, parent):1603 # name1604 if node.get('name') is None:1605 raise PeachException("No attribute name found on field element")1606 name = self._getAttribute(node, 'name')1607 # value1608 if node.get('value') is None:1609 raise PeachException("No attribute value found on Field element")1610 value = self._getAttribute(node, 'value')1611 field = Field(name, value, parent)1612 field.value = PeachStr(self.GetValueFromNode(node))1613 field.valueType = self._getValueType(node)1614 if field.name in parent:1615 parent[field.name] = field1616 else:1617 parent.append(field)1618 return field1619 # Handlers for Agent ###################################################1620 def HandleAgent(self, node, parent):1621 # name1622 name = self._getAttribute(node, 'name')1623 # ref1624 if node.get('ref') is not None:1625 if name is None or len(name) == 0:1626 name = Element.getUniqueName()1627 obj = self.GetRef(self._getAttribute(node, 'ref'))1628 agent = obj.copy(parent)1629 agent.name = name1630 agent.ref = self._getAttribute(node, 'ref')1631 else:1632 agent = Agent(name, parent)1633 #agent.node = node1634 agent.description = self._getAttribute(node, 'description')1635 agent.location = self._getAttribute(node, 'location')1636 if agent.location is None or len(agent.location) == 0:1637 agent.location = "LocalAgent"1638 #raise PeachException("Error: Agent definition must include location attribute.")1639 agent.password = self._getAttribute(node, 'password')1640 if agent.password is not None and len(agent.password) == 0:1641 agent.password = None1642 for child in node.iterchildren():1643 child_nodeName = split_ns(child.tag)[1]1644 if child_nodeName == 'Monitor':1645 if not self._getBooleanAttribute(child, "enabled"):1646 logging.info('Monitor "%s" is deactivated.' % self._getAttribute(child, "class"))1647 continue1648 if child.get("platform") is not None:1649 validOS = [x for x in self._getAttribute(child, "platform").split(",") if x == sys.platform]1650 if not validOS:1651 logging.debug('Monitor "%s" for %s is not supported on this platform.' %1652 (self._getAttribute(child, "class"), self._getAttribute(child, "platform")))1653 continue1654 agent.append(self.HandleMonitor(child, agent))1655 logging.info('Monitor "%s" attached.' % self._getAttribute(child, "class"))1656 elif child_nodeName == 'PythonPath':1657 p = self.HandlePythonPath(child, agent)1658 agent.append(p)1659 elif child_nodeName == 'Import':1660 p = self.HandleImport(child, agent)1661 agent.append(p)1662 else:1663 raise PeachException("Found unexpected child of Agent element")1664 ## A remote publisher might be in play1665 #if len(agent) < 1:1666 # raise Exception("Agent must have at least one Monitor child.")1667 return agent1668 def HandleMonitor(self, node, parent):1669 """1670 Handle Monitor element1671 """1672 name = self._getAttribute(node, 'name')1673 monitor = Monitor(name, parent)1674 # class1675 if node.get("class") is None:1676 raise PeachException("Monitor element missing class attribute")1677 monitor.classStr = self._getAttribute(node, "class")1678 # children1679 for child in node.iterchildren():1680 child_nodeName = split_ns(child.tag)[1]1681 if not child_nodeName == 'Param':1682 raise PeachException(PeachStr("Unexpected Monitor child node: %s" % child_nodeName))1683 param = self.HandleParam(child, parent)1684 monitor.params[param.name] = param.defaultValue1685 return monitor1686 # Handlers for Test ###################################################1687 def HandleTest(self, node, parent):1688 # name1689 name = self._getAttribute(node, 'name')1690 # ref1691 if node.get('ref') is not None:1692 if name is None or len(name) == 0:1693 name = Element.getUniqueName()1694 obj = self.GetRef(self._getAttribute(node, 'ref'), None, 'tests')1695 test = obj.copy(parent)1696 test.name = name1697 test.ref = self._getAttribute(node, 'ref')1698 else:1699 test = Test(name, parent)1700 #test.node = node1701 if node.get('description') is not None:1702 test.description = self._getAttribute(node, 'description')1703 test.mutators = None1704 for child in node.iterchildren():1705 child_nodeName = split_ns(child.tag)[1]1706 if child_nodeName == 'Publisher':1707 if not test.publishers:1708 test.publishers = []1709 pub = self.HandlePublisher(child, test)1710 test.publishers.append(pub)1711 test.append(pub.domPublisher)1712 elif child_nodeName == 'Agent':1713 if child.get('ref') is not None:1714 agent = self.GetRef(self._getAttribute(child, 'ref'), None, 'agents')1715 if agent is None:1716 raise PeachException(PeachStr("Unable to locate agent %s specified in Test element %s" % (1717 self._getAttribute(child, 'ref'), name)))1718 test.append(agent.copy(test))1719 elif child_nodeName == 'StateMachine' or child_nodeName == 'StateModel':1720 if child.get('ref') is None:1721 raise PeachException("StateMachine element in Test declaration must have a ref attribute.")1722 stateMachine = self.GetRef(self._getAttribute(child, 'ref'), None, 'children')1723 if stateMachine is None:1724 raise PeachException("Unable to locate StateMachine [%s] specified in Test [%s]" % (1725 str(self._getAttribute(child, 'ref')), name))1726 #print "*** StateMachine: ", stateMachine1727 test.stateMachine = stateMachine.copy(test)1728 test.append(test.stateMachine)1729 path = None1730 for child2 in child.iterchildren():1731 child2_nodeName = split_ns(child.tag)[1]1732 if child2_nodeName == 'Path':1733 path = self.HandlePath(child2, test.stateMachine)1734 test.stateMachine.append(path)1735 elif child2_nodeName == 'Stop':1736 if path is None:1737 raise PeachException("Stop element must be used after a Path element.")1738 path.stop = True1739 # Do not accept anything after Stop element ;)1740 break1741 elif child2_nodeName == 'Strategy':1742 strategy = self.HandleStrategy(child2, test.stateMachine)1743 test.stateMachine.append(strategy)1744 else:1745 raise PeachException("Unexpected node %s" % child2_nodeName)1746 elif child_nodeName == 'Mutator':1747 if child.get('class') is None:1748 raise PeachException("Mutator element does not have required class attribute")1749 mutator = Mutator(self._getAttribute(child, 'class'), test)1750 if not test.mutators:1751 test.mutators = Mutators(None, test)1752 mutator.parent = test.mutators1753 test.mutators.append(mutator)1754 elif child_nodeName == 'Include' or child_nodeName == 'Exclude':1755 self._HandleIncludeExclude(child, test)1756 elif child_nodeName == 'Strategy':1757 if self._getBooleanAttribute(child, "enabled"):1758 test.mutator = self.HandleFuzzingStrategy(child, test)1759 else:1760 raise PeachException("Found unexpected child of Test element")1761 if test.mutator is None:1762 test.mutator = MutationStrategy.DefaultStrategy(None, test)1763 if test.mutators is None:1764 # Add the default mutators instead of erroring out1765 test.mutators = self._locateDefaultMutators()1766 if test.template is None and test.stateMachine is None:1767 raise PeachException(PeachStr("Test %s does not have a Template or StateMachine defined" % name))1768 if len(test.publishers) == 0:1769 raise PeachException(PeachStr("Test %s does not have a publisher defined!" % name))1770 if test.template is not None and test.stateMachine is not None:1771 raise PeachException(PeachStr(1772 "Test %s has both a Template and StateMachine defined. Only one of them can be defined at a time." % name))1773 # Now mark Mutatable(being fuzzed) elements1774 # instructing on inclusions/exlusions1775 test.markMutatableElements(node)1776 return test1777 def HandleFuzzingStrategy(self, node, parent):1778 """1779 Handle parsing <Strategy> element that is a child of1780 <Test>1781 """1782 # name1783 name = self._getAttribute(node, 'name')1784 # class1785 cls = self._getAttribute(node, 'class')1786 # TODO why does this not work?1787 #return globals()["PeachXml_" + cls](node, parent)1788 exec("strategy = PeachXml_%s(node, parent)" % cls)1789 return strategy1790 def HandlePath(self, node, parent):1791 if node.get('ref') is None:1792 raise PeachException("Parser: Test::StateModel::Path missing ref attribute")1793 stateMachine = parent1794 ref = self._getAttribute(node, 'ref')1795 state = self.GetRef(ref, stateMachine, None)1796 path = Path(ref, parent)1797 for child in node.iterchildren():1798 child_nodeName = split_ns(child.tag)[1]1799 if child_nodeName == 'Include' or child_nodeName == 'Exclude':1800 self._HandleIncludeExclude(child, state)1801 elif child_nodeName == 'Data':1802 # Handle Data elements at Test-level1803 data = self.HandleData(child, path)1804 #data.node = child1805 actions = [child for child in state if child.elementType == 'action']1806 for action in actions:1807 cracker = DataCracker(action.getRoot())1808 cracker.optmizeModelForCracking(action.template)1809 action.template.setDefaults(data, self.dontCrack)1810 elif child_nodeName not in ['Mutator']:1811 raise PeachException("Found unexpected child of Path element")1812 return path1813 def _HandleIncludeExclude(self, node, parent):1814 ref = None1815 isExclude = split_ns(node.tag)[1] != 'Exclude'1816 if node.get('ref') is not None and node.get('xpath') is not None:1817 raise PeachException("Include/Exclude node can only have one of either ref or xpath attributes.")1818 if node.get('xpath') is not None:1819 xpath = self._getAttribute(node, 'xpath')1820 else:1821 ref = None1822 if node.get('ref') is not None:1823 ref = self._getAttribute(node, 'ref').replace('.', '/')1824 xpath = self._retrieveXPath(ref, node.getparent())1825 test = self._getTest(parent)1826 test.mutatables.append([isExclude, xpath])1827 def _getTest(self, element):1828 if element is None:1829 return None1830 if element.elementType == 'test':1831 return element1832 return self._getTest(element.parent)1833 def _retrieveXPath(self, xpath, node):1834 if split_ns(node.tag)[1] == 'Test':1835 if xpath is None:1836 return "//*"1837 else:1838 return "//%s" % xpath1839 if node.get('ref') is None:1840 raise PeachException("All upper elements must have a ref attribute. Cannot retrieve relative XPath.")1841 ref = self._getAttribute(node, 'ref')1842 if xpath is not None:1843 xpath = ref + "/" + xpath1844 else:1845 xpath = ref1846 return self._retrieveXPath(xpath, node.getparent())1847 def HandleStrategy(self, node, parent):1848 # class1849 if node.get("class") is None:1850 raise PeachException("Strategy element missing class attribute")1851 classStr = self._getAttribute(node, "class")1852 strategy = Strategy(classStr, parent)1853 # children1854 for child in node.iterchildren():1855 child_nodeName = split_ns(child.tag)[1]1856 if not child_nodeName == 'Param':1857 raise PeachException(PeachStr("Unexpected Strategy child node: %s" % child_nodeName))1858 param = self.HandleParam(child, parent)1859 strategy.params[param.name] = eval(param.defaultValue)1860 return strategy1861 def _locateDefaultMutators(self, obj=None):1862 """1863 Look for a default set of mutators. We will follow this1864 search pattern:1865 1. Look at our self (context) level1866 2. Look at our imported namespaces1867 3. Recerse into namespaces (sub namespaces, etc)1868 This means a <Mutators> element in the top level XML file will1869 get precidence over the defaults.xml file which is included into1870 a namepsace.1871 """1872 if obj is None:1873 obj = self.context1874 # First look at us1875 if obj.mutators is not None:1876 return obj.mutators1877 # Now look at namespaces1878 for n in obj:1879 if n.elementType == 'namespace':1880 if n.ns.mutators is not None:1881 return n.ns.mutators1882 # Now look inside namespace1883 for n in obj:1884 if n.elementType == 'namespace':1885 m = self._locateDefaultMutators(n.ns)1886 if m is not None:1887 return m1888 # YUCK1889 raise PeachException("Could not locate default set of Mutators to use. Please fix this!")1890 def HandleRun(self, node, parent):1891 haveLogger = False1892 # name1893 name = None1894 if node.get('name') is not None:1895 name = self._getAttribute(node, 'name')1896 run = Run(name, parent)1897 #run.node = node1898 run.description = self._getAttribute(node, 'description')1899 if node.get('waitTime') is not None:1900 run.waitTime = float(self._getAttribute(node, 'waitTime'))1901 for child in node.iterchildren():1902 child_nodeName = split_ns(child.tag)[1]1903 if child_nodeName == 'Test':1904 test = None1905 if child.get('ref') is not None:1906 test = self.GetRef(self._getAttribute(child, 'ref'), None, 'tests')1907 if test is None:1908 raise PeachException(1909 PeachStr("Unable to locate tests %s specified in Run element %s" % (testsName, name)))1910 test = test.copy(run)1911 run.tests.append(test)1912 run.append(test)1913 elif child_nodeName == 'Logger':1914 if not self._getBooleanAttribute(child, "enabled"):1915 continue1916 loggerName = self._getAttribute(child, "class")1917 try:1918 logger = self.HandleLogger(child, run)1919 except Exception as msg:1920 logging.warning(highlight.warning("Unable to attach %s: %s" % (loggerName, msg)))1921 continue1922 logging.info('Logger "%s" attached.' % loggerName)1923 run.append(logger)1924 haveLogger = True1925 else:1926 raise PeachException("Found unexpected child of Run element")1927 if len(run.tests) == 0:1928 raise PeachException(PeachStr("Run %s does not have any tests defined!" % name))1929 if not haveLogger:1930 logging.warning("Run '%s' does not have logging configured!" % name)1931 return run1932 def HandlePublisher(self, node, parent):1933 params = []1934 publisher = Publisher()1935 # class1936 if node.get("class") is None:1937 raise PeachException("Publisher element missing class attribute")1938 if len(node.get("class")) == 0:1939 raise PeachException("Publisher class attribute is empty")1940 publisher.classStr = publisherClass = self._getAttribute(node, "class")1941 if node.get("name") is not None:1942 publisher.name = self._getAttribute(node, "name")1943 # children1944 for child in node.iterchildren():1945 child_nodeName = split_ns(child.tag)[1]1946 if child.get("name") is None:1947 raise PeachException("Publisher element missing name attribute")1948 if child.get("value") is None:1949 raise PeachException("Publisher element missing value attribute")1950 if child.get("valueType") is None:1951 valueType = "string"1952 else:1953 valueType = self._getAttribute(child, "valueType")1954 name = self._getAttribute(child, "name")1955 value = self._getAttribute(child, "value")1956 param = Param(publisher)1957 param.name = name1958 param.defaultValue = PeachStr(value)1959 param.valueType = valueType1960 if valueType == 'string':1961 # create a literal out of a string value1962 value = "'''" + value + "'''"1963 elif valueType == 'hex':1964 ret = ''1965 valueLen = len(value) + 11966 while valueLen > len(value):1967 valueLen = len(value)1968 for i in range(len(self._regsHex)):1969 match = self._regsHex[i].search(value)1970 if match is not None:1971 while match is not None:1972 ret += '\\x' + match.group(2)1973 value = self._regsHex[i].sub('', value)1974 match = self._regsHex[i].search(value)1975 break1976 value = "'" + ret + "'"1977 publisher.append(param)1978 params.append([name, value])1979 code = "PeachXml_%s(%s)" % (publisherClass, ",".join(str(v) for _,v in params))1980 pub = eval(code, globals(), locals())1981 pub.domPublisher = publisher1982 pub.parent = parent1983 return pub1984 def HandleLogger(self, node, parent):1985 params = {}1986 logger = Logger(parent)1987 #logger.node = node1988 # class1989 if node.get("class") is None:1990 raise PeachException("Logger element missing class attribute")1991 logger.classStr = self._getAttribute(node, "class")1992 # children1993 for child in node.iterchildren():1994 child_nodeName = split_ns(child.tag)[1]1995 if child.get("name") is None:1996 raise PeachException("Logger element missing name attribute")1997 if child.get("value") is None:1998 raise PeachException("Logger element missing value attribute")1999 if child.get("valueType") is None:2000 valueType = "string"2001 else:2002 valueType = self._getAttribute(child, "valueType")2003 name = self._getAttribute(child, "name")2004 value = self._getAttribute(child, "value")2005 param = Param(logger)2006 param.name = name2007 param.defaultValue = PeachStr(value)2008 param.valueType = valueType2009 if valueType == 'string':2010 # create a literal out of a string value2011 value = "'''" + value + "'''"2012 elif valueType == 'hex':2013 ret = ''2014 valueLen = len(value) + 12015 while valueLen > len(value):2016 valueLen = len(value)2017 for i in range(len(self._regsHex)):2018 match = self._regsHex[i].search(value)2019 if match is not None:2020 while match is not None:2021 ret += '\\x' + match.group(2)2022 value = self._regsHex[i].sub('', value)2023 match = self._regsHex[i].search(value)2024 break2025 value = "'" + ret + "'"2026 #print "LoggeR: Adding %s:%s" % (PeachStr(name),PeachStr(value))2027 logger.append(param)2028 params[PeachStr(name)] = PeachStr(value)2029 code = "PeachXml_" + logger.classStr + '(params)'2030 pub = eval(code)2031 pub.domLogger = logger2032 return pub2033 def HandleStateMachine(self, node, parent):2034 if node.get("name") is None:2035 raise PeachException("Parser: StateMachine missing name attribute")2036 if node.get('initialState') is None:2037 raise PeachException("Parser: StateMachine missing initialState attribute")2038 stateMachine = StateMachine(self._getAttribute(node, "name"), parent)2039 stateMachine.initialState = self._getAttribute(node, 'initialState')2040 stateMachine.onLoad = self._getAttribute(node, 'onLoad')2041 for child in node.iterchildren():2042 child_nodeName = split_ns(child.tag)[1]2043 if child_nodeName == 'State':2044 state = self.HandleState(child, stateMachine)2045 stateMachine.append(state)2046 else:2047 raise PeachException("Parser: StateMachine has unknown child [%s]" % PeachStr(child_nodeName))2048 return stateMachine2049 def HandleState(self, node, parent):2050 if node.get("name") is None:2051 raise PeachException("Parser: State missing name attribute")2052 state = State(self._getAttribute(node, 'name'), parent)2053 state.onEnter = self._getAttribute(node, 'onEnter')2054 state.onExit = self._getAttribute(node, 'onExit')2055 foundAction = False2056 for child in node.iterchildren():2057 child_nodeName = split_ns(child.tag)[1]2058 if child_nodeName == 'Action':2059 action = self.HandleAction(child, state)2060 if action.name in state:2061 raise PeachException("Found duplicate Action name [%s]!" % action.name)2062 state.append(action)2063 foundAction = True2064 elif child_nodeName == 'Choice':2065 choice = self.HandleStateChoice(child, state)2066 state.append(choice)2067 else:2068 raise PeachException("Parser: State has unknown child [%s]" % PeachStr(child_nodeName))2069 if not foundAction:2070 raise PeachException("State [%s] has no actions" % state.name)2071 return state2072 def HandleStateChoice(self, node, parent):2073 choice = StateChoice(parent)2074 for child in node.iterchildren():2075 choice.append(self.HandleStateChoiceAction(child, node))2076 return choice2077 def HandleStateChoiceAction(self, node, parent):2078 if node.get("ref") is None:2079 raise PeachException("Parser: State::Choice::Action missing ref attribute")2080 if node.get("type") is None:2081 raise PeachException("Parser: State::Choice::Action missing type attribute")2082 ref = self._getAttribute(node, "ref")2083 type = self._getAttribute(node, "type")2084 return StateChoiceAction(ref, type, parent)2085 def HandleAction(self, node, parent):2086 if node.get("type") is None:2087 raise PeachException("Parser: Action missing 'type' attribute")2088 action = Action(self._getAttribute(node, 'name'), parent)2089 action.type = self._getAttribute(node, 'type')2090 if not action.type in ['input', 'output', 'call', 'setprop', 'getprop', 'changeState',2091 'slurp', 'connect', 'close', 'accept', 'start', 'stop', 'wait', 'open']:2092 raise PeachException("Parser: Action type attribute is not valid [%s]." % action.type)2093 action.onStart = self._getAttribute(node, 'onStart')2094 action.onComplete = self._getAttribute(node, 'onComplete')2095 action.when = self._getAttribute(node, 'when')2096 action.ref = self._getAttribute(node, 'ref')2097 action.setXpath = self._getAttribute(node, 'setXpath')2098 action.valueXpath = self._getAttribute(node, 'valueXpath')2099 action.valueLiteral = self._getAttribute(node, 'value')2100 action.method = self._getAttribute(node, 'method')2101 action.property = self._getAttribute(node, 'property')2102 action.publisher = self._getAttribute(node, 'publisher')2103 # Quick hack to get open support. open and connect are same.2104 if action.type == 'open':2105 action.type = 'connect'2106 if (action.setXpath or action.valueXpath or action.valueLiteral) and (2107 action.type != 'slurp' and action.type != 'wait'):2108 raise PeachException("Parser: Invalid attribute for Action were type != 'slurp'")2109 if action.method is not None and action.type != 'call':2110 raise PeachException("Parser: Method attribute on an Action only available when type is 'call'.")2111 if action.property is not None and not action.type in ['setprop', 'getprop']:2112 raise PeachException(2113 "Parser: Property attribute on an Action only available when type is 'setprop' or 'getprop'.")2114 for child in node.iterchildren():2115 child_nodeName = split_ns(child.tag)[1]2116 if child_nodeName == 'Param':2117 if not action.type in ['call', 'setprop', 'getprop']:2118 raise PeachException("Parser: Param is an invalid child of Action for this Action type")2119 param = self.HandleActionParam(child, action)2120 if param.name in action:2121 raise PeachException(2122 "Error, duplicate Param name [%s] found in Action [%s]." % (param.name, action.name))2123 action.append(param)2124 elif child_nodeName == 'Template' or child_nodeName == 'DataModel':2125 if action.type not in ['input', 'output', 'getprop']:2126 raise PeachException("Parser: DataModel is an invalid child of Action for this Action type")2127 #if child.get('ref') is None:2128 # raise PeachException("Parser: When DataModel is a child of Action it must have the ref attribute.")2129 if action.template is not None:2130 raise PeachException("Error, action [%s] already has a DataModel specified." % action.name)2131 obj = self.HandleTemplate(child, action)2132 action.template = obj2133 action.append(obj)2134 elif child_nodeName == 'Data':2135 if not (action.type == 'input' or action.type == 'output'):2136 raise PeachException("Parser: Data is an invalid child of Action for this Action type")2137 if action.data is not None:2138 raise PeachException("Error, action [%s] already has a Data element specified." % action.name)2139 data = self.HandleData(child, action)2140 action.data = data2141 elif child_nodeName == 'Result':2142 if not action.type in ['call']:2143 raise PeachException("Parser: Result is an invalid child of Action of type 'call'.")2144 result = self.HandleActionResult(child, action)2145 if result.name in action:2146 raise PeachException(2147 "Error, duplicate Result name [%s] found in Action [%s]." % (param.name, action.name))2148 action.append(result)2149 else:2150 raise PeachException("Parser: State has unknown child [%s]" % PeachStr(child_nodeName))2151 if action.template is not None and action.data is not None:2152 cracker = DataCracker(action.getRoot())2153 cracker.optmizeModelForCracking(action.template)2154 # Somehow data not getting parent. Force setting2155 action.data.parent = action2156 action.template.setDefaults(action.data, self.dontCrack, True)2157 # Verify action has a DataModel if needed2158 if action.type in ['input', 'output']:2159 if action.template is None:2160 raise PeachException("Parser: Action [%s] of type [%s] must have a DataModel child element." % (2161 action.name, action.type))2162 # Verify that setprop has a parameter2163 if action.type == 'setprop':2164 foundActionParam = False2165 for c in action:2166 if isinstance(c, ActionParam):2167 foundActionParam = True2168 if not foundActionParam:2169 raise PeachException(2170 "Parser: Action [%s] of type [%s] must have a Param child element." % (action.name, action.type))2171 return action2172 def HandleActionParam(self, node, parent):2173 if node.get("type") is None:2174 raise PeachException("Parser: ActionParam missing required type attribute")2175 param = ActionParam(self._getAttribute(node, 'name'), parent)2176 param.type = self._getAttribute(node, 'type')2177 if not param.type in ['in', 'out', 'inout', 'return']:2178 raise PeachException(2179 "Parser: ActionParam type attribute is not valid [%s]. Must be one of: in, out, or inout" % param.type)2180 for child in node.iterchildren():2181 child_nodeName = split_ns(child.tag)[1]2182 if child_nodeName == 'Template' or child_nodeName == 'DataModel':2183 #if child.get('ref') is None:2184 # raise PeachException("Parser: When Template is a child of ActionParam it must have the ref attribute.")2185 obj = self.HandleTemplate(child, param)2186 param.template = obj2187 param.append(obj)2188 elif child_nodeName == 'Data':2189 if not (param.type == 'in' or param.type == 'inout'):2190 raise PeachException(2191 "Parser: Data is an invalid child of ActionParam for this type [%s]" % param.type)2192 data = self.HandleData(child, param)2193 data.parent = param2194 param.data = data2195 else:2196 raise PeachException("Parser: ActionParam has unknown child [%s]" % PeachStr(child_nodeName))2197 if param.template is not None and param.data is not None:2198 cracker = DataCracker(param.template.getRoot())2199 cracker.optmizeModelForCracking(param.template)2200 param.template.setDefaults(param.data, self.dontCrack, True)2201 # Verify param has data model2202 if param.template is None:2203 raise PeachException("Parser: Action Param must have DataModel as child element.")2204 return param2205 def HandleActionResult(self, node, parent):2206 result = ActionResult(self._getAttribute(node, 'name'), parent)2207 for child in node.iterchildren():2208 child_nodeName = split_ns(child.tag)[1]2209 if child_nodeName == 'Template' or child_nodeName == 'DataModel':2210 if child.get('ref') is None:2211 raise PeachException(2212 "Parser: When Template is a child of ActionParam it must have the ref attribute.")2213 obj = self.HandleTemplate(child, result)2214 result.template = obj2215 result.append(obj)2216 else:2217 raise PeachException("Parser: Action Result has unknown child [%s]" % PeachStr(child_nodeName))2218 # Verify param has data model2219 if result.template is None:2220 raise PeachException("Parser: Action Result must have DataModel as child element.")2221 return result2222 def _HandleValueType(self, value, valueType):2223 """2224 Handle types: string, literal, and hex2225 """2226 if not value or not valueType:2227 return None2228 if valueType == 'literal':2229 return PeachStr(eval(value))2230 return PeachStr(value)2231 def _HandleValueTypeString(self, value, valueType):2232 """2233 Handle types: string, literal, and hex2234 """2235 if not value or not valueType:2236 return None2237 if valueType == 'literal':2238 return eval(value)2239 return value2240 def HandleParam(self, node, parent):2241 param = Param(parent)2242 if node.get("name") is None:2243 raise PeachException(2244 "Parser: Param element missing name attribute. Parent is [{}]".format(split_ns(node.getparent().tag)[1]))2245 if node.get("value") is None:2246 raise PeachException("Parser: Param element missing value attribute. Name is [{}]. Parent is [{}]".format(node.get("name"), split_ns(node.getparent().tag)[1]))2247 if node.get("valueType") is None:2248 valueType = "string"2249 else:2250 valueType = self._getAttribute(node, "valueType")2251 name = self._getAttribute(node, "name")2252 value = self._getAttribute(node, "value")2253 if valueType == 'string':2254 # create a literal out of a string value2255 try:2256 value = "'''" + value + "'''"2257 except TypeError:2258 raise PeachException("Parser: Failed converting param value to string. Name is [{}]. Value is [{}].".format(name, value))2259 elif valueType == 'hex':2260 ret = ''2261 valueLen = len(value) + 12262 while valueLen > len(value):2263 valueLen = len(value)2264 for i in range(len(self._regsHex)):2265 match = self._regsHex[i].search(value)2266 if match is not None:2267 while match is not None:2268 ret += '\\x' + match.group(2)2269 value = self._regsHex[i].sub('', value)2270 match = self._regsHex[i].search(value)2271 break2272 value = "'" + ret + "'"2273 param.name = name2274 param.defaultValue = PeachStr(value)2275 param.valueType = valueType2276 return param2277 def HandlePythonPath(self, node, parent):2278 if node.get('path') is None:2279 raise PeachException("PythonPath element did not have a path attribute!")2280 p = PythonPath()2281 p.name = self._getAttribute(node, 'path')2282 return p2283 def HandleImport(self, node, parent):2284 # Import module2285 if node.get('import') is None:2286 raise PeachException("HandleImport: Import element did not have import attribute!")2287 i = Element()2288 i.elementType = 'import'2289 i.importStr = self._getAttribute(node, 'import')2290 if node.get('from') is not None:2291 i.fromStr = self._getAttribute(node, 'from')2292 else:2293 i.fromStr = None2294 return i2295 def HandleHint(self, node, parent):2296 if node.get('name') is None or node.get('value') is None:2297 raise PeachException("Error: Found Hint element that didn't have both name and value attributes.")2298 hint = Hint(self._getAttribute(node, 'name'), parent)2299 hint.value = self._getAttribute(node, 'value')2300 parent.hints.append(hint)2301 return hint...

Full Screen

Full Screen

Config.py

Source:Config.py Github

copy

Full Screen

...31 for config in configs:32 itemList = config.getElementsByTagName('add')33 for item in itemList:34 node = item.parentNode.nodeName35 key = _getAttribute(item, 'key')36 value = _getAttribute(item, 'value')37 if node in self.__CONFIG_MAP:38 self.__CONFIG_MAP[node][key] = value39 else:40 self.__CONFIG_MAP[node] = {}41 self.__CONFIG_MAP[node][key] = value42 def GetSetting(self, group, key):43 ret = None44 while True:45 if group not in self.__CONFIG_MAP:46 break47 if key not in self.__CONFIG_MAP[group]:48 break49 ret = copy.copy(self.__CONFIG_MAP[group][key])50 break51 return ret52class __ParserRouter__(metaclass=Common.__Singleton__):53 """54 解析模块关系配置,存储在 DATA/CONFIG 下的 ROUTER.XML 文件当中,55 模块关系对应路由关系,每个配置都对应响应的模块文件,数据模型和对象56 """57 def __init__(self):58 self.__CONFIG_FILE = 'router.xml'59 self.__CONFIG_MAP = {}60 # 创建实例时初始化配置61 self.__Parser()62 def __Parser(self):63 fullPath = Common.GetConfigPath() + self.__CONFIG_FILE64 # 使用minidom解析器打开 XML 文档65 DOMTree = xml.dom.minidom.parse(fullPath)66 root = DOMTree.documentElement67 # 在集合中获取所有配置68 configs = root.getElementsByTagName('configuration')[0]69 # 遍历配置并读取和存储内容70 itemList = configs.getElementsByTagName('add')71 for item in itemList:72 module = _getAttribute(item, 'module')73 handler = _getAttribute(item, 'handler')74 auth = _getAttribute(item, 'auth')75 encrypt = _getAttribute(item, 'encrypt')76 ver = _getAttribute(item, 'version')77 datatype = _getAttribute(item, 'datatype')78 resultype = _getAttribute(item, 'resultype')79 if ver not in self.__CONFIG_MAP:80 self.__CONFIG_MAP[ver] = {}81 if module not in self.__CONFIG_MAP[ver]:82 self.__CONFIG_MAP[ver][module] = {}83 if handler not in self.__CONFIG_MAP[ver][module]:84 self.__CONFIG_MAP[ver][module][handler] = {}85 self.__CONFIG_MAP[ver][module][handler]['version'] = ver86 self.__CONFIG_MAP[ver][module][handler]['auth'] = auth87 self.__CONFIG_MAP[ver][module][handler]['encrypt'] = encrypt88 self.__CONFIG_MAP[ver][module][handler]['datatype'] = datatype89 self.__CONFIG_MAP[ver][module][handler]['resultype'] = resultype90 def GetModuleByName(self, ver, module):91 if ver in self.__CONFIG_MAP:92 if module in self.__CONFIG_MAP[ver]:93 return copy.copy(self.__CONFIG_MAP[ver][module])94 else:95 return None96 else:97 return None98 def GetRouterByName(self, ver, module, handler):99 ret = None100 while True:101 if ver not in self.__CONFIG_MAP:102 break103 if module not in self.__CONFIG_MAP[ver]:104 break105 if handler not in self.__CONFIG_MAP[ver][module]:106 break107 ret = copy.copy(self.__CONFIG_MAP[ver][module][handler])108 break109 return ret110 def GetAllModule(self):111 return copy.copy(self.__CONFIG_MAP)112class __ParserModel__(metaclass=Common.__Singleton__):113 """114 解析数据模型配置文件,每个模型都将杯格式化为对象,115 模块和框架数据交互只能通过数据模型对象116 """117 def __init__(self):118 self.__CONFIG_FILE = 'model.xml'119 self.__CONFIG_MAP = {}120 self.__Parser()121 def __Parser(self):122 fullPath = Common.GetConfigPath() + self.__CONFIG_FILE123 # 使用minidom解析器打开 XML 文档124 DOMTree = xml.dom.minidom.parse(fullPath)125 root = DOMTree.documentElement126 # 在集合中获取所有配置127 configs = root.getElementsByTagName('models')[0]128 itmeList = configs.getElementsByTagName('add')129 for item in itmeList:130 # 根据数据模型名称建立和参数的对应关系131 modelName = _getAttribute(item, 'name')132 params = item.getElementsByTagName('parameter')133 pdic = {}134 for param in params:135 pname = _getAttribute(param, 'name')136 pdic[pname] = {}137 pdic[pname]['type'] = _getAttribute(param, 'type')138 pdic[pname]['value'] = _getAttribute(param, 'value')139 pdic[pname]['isempty'] = _getAttribute(param, 'isempty')140 pdic[pname]['extype'] = _getAttribute(param, 'extype')141 pdic[pname]['description'] = _getAttribute(param, 'description')142 self.__CONFIG_MAP[modelName] = pdic143 def GetModelByName(self, name):144 if name in self.__CONFIG_MAP:145 return copy.copy(self.__CONFIG_MAP[name])146 else:147 return None148 def HasModel(self, name):149 return name in self.__CONFIG_MAP150class __ParserSQL__(metaclass=Common.__Singleton__):151 """152 解析数据库IO配置,分四类,每个SQL语句为单位,每个参数需要检查数据类型153 """154 def __init__(self):155 self.__CONFIG_FILE = 'sql.xml'156 self.__CONFIG_SELECT_MAP = {}157 self.__CONFIG_UPDATE_MAP = {}158 self.__CONFIG_INSERT_MAP = {}159 self.__CONFIG_DELETE_MAP = {}160 self.__Parser()161 def __Parser(self):162 fullPath = Common.GetConfigPath() + self.__CONFIG_FILE163 # 使用minidom解析器打开 XML 文档164 DOMTree = xml.dom.minidom.parse(fullPath)165 root = DOMTree.documentElement166 # 在集合中获取所有配置167 configs = root.getElementsByTagName('sqls')[0]168 selects = configs.getElementsByTagName('select')[0]169 selects = selects.getElementsByTagName('add')170 # 获取所有 select 语句171 for item in selects:172 name = _getAttribute(item, 'name')173 content = _getAttribute(item, 'content')174 description = _getAttribute(item, 'description')175 params = item.getElementsByTagName('parameter')176 pdic = {}177 for param in params:178 pname = _getAttribute(param, 'name')179 pdic[pname] = {}180 pdic[pname]['type'] = _getAttribute(param, 'type')181 pdic[pname]['value'] = _getAttribute(param, 'value')182 self.__CONFIG_SELECT_MAP[name] = {}183 self.__CONFIG_SELECT_MAP[name]['content'] = content184 self.__CONFIG_SELECT_MAP[name]['params'] = pdic185 self.__CONFIG_SELECT_MAP[name]['description'] = description186 updates = configs.getElementsByTagName('update')[0]187 updates = updates.getElementsByTagName('add')188 # 获取所有 UPDATE 语句189 for item in updates:190 name = _getAttribute(item, 'name')191 content = _getAttribute(item, 'content')192 description = _getAttribute(item, 'description')193 params = item.getElementsByTagName('parameter')194 pdic = {}195 for param in params:196 pname = _getAttribute(param, 'name')197 pdic[pname] = {}198 pdic[pname]['type'] = _getAttribute(param, 'type')199 pdic[pname]['value'] = _getAttribute(param, 'value')200 self.__CONFIG_UPDATE_MAP[name] = {}201 self.__CONFIG_UPDATE_MAP[name]['content'] = content202 self.__CONFIG_UPDATE_MAP[name]['params'] = pdic203 self.__CONFIG_UPDATE_MAP[name]['description'] = description204 inserts = configs.getElementsByTagName('insert')[0]205 inserts = inserts.getElementsByTagName('add')206 # 获取所有 INSERT 语句207 for item in inserts:208 name = _getAttribute(item, 'name')209 content = _getAttribute(item, 'content')210 description = _getAttribute(item, 'description')211 params = item.getElementsByTagName('parameter')212 pdic = {}213 for param in params:214 pname = _getAttribute(param, 'name')215 pdic[pname] = {}216 pdic[pname]['type'] = _getAttribute(param, 'type')217 pdic[pname]['value'] = _getAttribute(param, 'value')218 self.__CONFIG_INSERT_MAP[name] = {}219 self.__CONFIG_INSERT_MAP[name]['content'] = content220 self.__CONFIG_INSERT_MAP[name]['params'] = pdic221 self.__CONFIG_INSERT_MAP[name]['description'] = description222 deletes = configs.getElementsByTagName('delete')[0]223 deletes = deletes.getElementsByTagName('add')224 # 获取所有 DELETE 语句225 for item in deletes:226 name = _getAttribute(item, 'name')227 content = _getAttribute(item, 'content')228 description = _getAttribute(item, 'description')229 params = item.getElementsByTagName('parameter')230 pdic = {}231 for param in params:232 pname = _getAttribute(param, 'name')233 pdic[pname] = {}234 pdic[pname]['type'] = _getAttribute(param, 'type')235 pdic[pname]['value'] = _getAttribute(param, 'value')236 self.__CONFIG_DELETE_MAP[name] = {}237 self.__CONFIG_DELETE_MAP[name]['content'] = content238 self.__CONFIG_DELETE_MAP[name]['params'] = pdic239 self.__CONFIG_DELETE_MAP[name]['description'] = description240 def GetSelectSQLByName(self, name):241 """获取 SELECT 配置 SQL 语句"""242 if name in self.__CONFIG_SELECT_MAP:243 return copy.copy(self.__CONFIG_SELECT_MAP[name]['content'])244 else:245 return None246 def GetSelectParamByName(self, name):247 """获取 SELECT 配置 SQL 参数"""248 if name in self.__CONFIG_SELECT_MAP:249 return copy.copy(self.__CONFIG_SELECT_MAP[name]['params'])250 else:251 return None252 def GetInsertSQLByName(self, name):253 if name in self.__CONFIG_INSERT_MAP:254 return copy.copy(self.__CONFIG_INSERT_MAP[name]['content'])255 else:256 return None257 def GetInsertParamByName(self, name):258 if name in self.__CONFIG_INSERT_MAP:259 return copy.copy(self.__CONFIG_INSERT_MAP[name]['params'])260 else:261 return None262 def GetUpdateSQLByName(self, name):263 if name in self.__CONFIG_UPDATE_MAP:264 return copy.copy(self.__CONFIG_UPDATE_MAP[name]['content'])265 else:266 return None267 def GetUpdateParamByName(self, name):268 if name in self.__CONFIG_UPDATE_MAP:269 return copy.copy(self.__CONFIG_UPDATE_MAP[name]['params'])270 else:271 return None272 def GetDeleteSQLByName(self, name):273 if name in self.__CONFIG_DELETE_MAP:274 return copy.copy(self.__CONFIG_DELETE_MAP[name]['content'])275 else:276 return None277 def GetDeleteParamByName(self, name):278 if name in self.__CONFIG_DELETE_MAP:279 return copy.copy(self.__CONFIG_DELETE_MAP[name]['params'])280 else:281 return None282class __ParserAppConfig__(metaclass=Common.__Singleton__):283 """284 解析 DATA/CONFIG 目录中的 APPCONFIG.XML 文件,285 将该 XML 格式化为字典,存放在单例对象成员中。286 """287 def __init__(self):288 self.__CONFIG_FILE = 'appconfig.xml'289 self.__CONFIG_MAP = {}290 self.__Parser()291 def __Parser(self):292 fullPath = Common.GetConfigPath() + self.__CONFIG_FILE293 # 使用minidom解析器打开 XML 文档294 DOMTree = xml.dom.minidom.parse(fullPath)295 root = DOMTree.documentElement296 # 在集合中获取所有配置297 configs = root.getElementsByTagName('configuration')298 # 遍历配置并读取和存储内容299 for config in configs:300 itemList = config.getElementsByTagName('add')301 for item in itemList:302 node = item.parentNode.nodeName303 key = _getAttribute(item, 'key')304 value = _getAttribute(item, 'value')305 if node in self.__CONFIG_MAP:306 self.__CONFIG_MAP[node][key] = value307 else:308 self.__CONFIG_MAP[node] = {}309 self.__CONFIG_MAP[node][key] = value310 def GetSetting(self, group, key):311 ret = None312 while True:313 if group not in self.__CONFIG_MAP:314 break315 if key not in self.__CONFIG_MAP[group]:316 break317 ret = copy.copy(self.__CONFIG_MAP[group][key])318 break319 return ret320class __ParserCode__(metaclass=Common.__Singleton__):321 """解析 DATA/CONFIG 目录中的 ERROR.XML 文件"""322 def __init__(self):323 self.__CONFIG_FILE = 'error.xml'324 self.__CONFIG_MAP = {}325 self.__Parser()326 def __Parser(self):327 fullPath = Common.GetConfigPath() + self.__CONFIG_FILE328 # 使用minidom解析器打开 XML 文档329 DOMTree = xml.dom.minidom.parse(fullPath)330 root = DOMTree.documentElement331 # 在集合中获取所有配置332 retCodes = root.getElementsByTagName('retcode')[0]333 # 遍历配置并读取 RETCODE 内容334 itemList = retCodes.getElementsByTagName('add')335 for item in itemList:336 node = item.parentNode.nodeName337 key = _getAttribute(item, 'name')338 value = _getAttribute(item, 'value')339 if node in self.__CONFIG_MAP:340 self.__CONFIG_MAP[node][key] = value341 else:342 self.__CONFIG_MAP[node] = {}343 self.__CONFIG_MAP[node][key] = value344 # 在集合中获取所有配置345 apiCodes = root.getElementsByTagName('apicode')[0]346 itemList = apiCodes.getElementsByTagName('add')347 for item in itemList:348 node = item.parentNode.nodeName349 key = _getAttribute(item, 'name')350 value = _getAttribute(item, 'value')351 if node in self.__CONFIG_MAP:352 self.__CONFIG_MAP[node][key] = value353 else:354 self.__CONFIG_MAP[node] = {}355 self.__CONFIG_MAP[node][key] = value356 def GetCodeById(self, c_type, c_id):357 """根据ID读取代码说明"""358 ret = None359 while True:360 if c_type not in self.__CONFIG_MAP:361 break362 if c_id not in self.__CONFIG_MAP[c_type]:363 break364 ret = copy.copy(self.__CONFIG_MAP[c_type][c_id])365 break366 return ret367def GetRouterByName(version, module, handler):368 """获取模块对应的 Handler 信息"""369 PR = __ParserRouter__()370 return PR.GetRouterByName(version, module, handler)371def GetAllModule():372 """获取所有模块信息"""373 PR = __ParserRouter__()374 return PR.GetAllModule()375def GetModelByName(name):376 """依据名称获取数据类型"""377 PM = __ParserModel__()378 return PM.GetModelByName(name)379def GetSelectSQLByName(name):380 """获取 SELECT 配置 SQL 语句"""381 PS = __ParserSQL__()382 return PS.GetSelectSQLByName(name)383def GetSelectParamByName(name):384 """获取 SELECT 配置 SQL 参数"""385 PS = __ParserSQL__()386 return PS.GetSelectParamByName(name)387def GetInsertSQLByName(name):388 """获取 Insert 配置 SQL 语句"""389 PS = __ParserSQL__()390 return PS.GetInsertSQLByName(name)391def GetInsertParamByName(name):392 """获取 Insert 配置 SQL 参数"""393 PS = __ParserSQL__()394 return PS.GetInsertParamByName(name)395def GetUpdateSQLByName(name):396 """获取 Update 配置 SQL 语句"""397 PS = __ParserSQL__()398 return PS.GetUpdateSQLByName(name)399def GetUpdateParamByName(name):400 """获取 Update 配置 SQL 参数"""401 PS = __ParserSQL__()402 return PS.GetUpdateParamByName(name)403def GetDeleteSQLByName(name):404 """获取 Delete 配置 SQL 语句"""405 PS = __ParserSQL__()406 return PS.GetDeleteSQLByName(name)407def GetDeleteParamByName(name):408 """获取 Delete 配置 SQL 参数"""409 PS = __ParserSQL__()410 return PS.GetDeleteParamByName(name)411def GetSysSetting(group, key):412 """获取应用程序配置"""413 PC = __ParserConfig__()414 return PC.GetSetting(group, key)415def GetAppConfig(group, key):416 """"""417 PC = __ParserAppConfig__()418 return PC.GetSetting(group, key)419def GetCodeById(c_type, c_id):420 """依据名称获取数据类型"""421 PC = __ParserCode__()422 return PC.GetCodeById(c_type, c_id)423def _getAttribute(obj, name):424 """重写获取属性方法,转换字符集"""...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run pyatom automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful