📄 nescdecls.py
字号:
def getBytes(self) : bytes = pack (str(self.size)+"s",'\x00') if len(bytes) != self.size: raise Exception("Byte conversion error: %s %d bytes to %d" % (self.nescType, len(bytes), self.size) ) return bytes def setBytes(self, bytes) : if len(bytes) < self.size: raise Exception("Byte conversion error: %s %d bytes to %d" % ( self.nescType, len(bytes), self.size) ) return bytes[self.size:]############ Struct of basic nesc types,###########class nescStruct( object ) : """A python representation of a nesc structure. usage: struct = nescStruct(myTypes, xmlDecl) struct = nescStruct(structName, (fieldName, type) (fieldName, type), ...) X = struct.field struct.field = X bytes = struct.getBytes() struct.setBytes(bytes) struct print struct """ def __init__( self, *varargs) : """initialize all fields to 0""" self.__dict__["value"] = {} self.fields = [] self.size = 0 if len(varargs) == 0 : self.nescType = "" #create the struct from nescType args elif len(varargs) >= 1 and ( type(varargs[0]) == str or type(varargs[0]) == unicode ) : self.nescType = varargs[0] self._parseNescTypeFields(varargs[1:]) ## parse the struct def from xml elif len(varargs) == 2 and type(varargs[1]) != tuple : (nescTypes, xmlDefinition) = varargs[:] if xmlDefinition.tagName != "struct" : raise Exception("Not struct definition") if xmlDefinition.hasAttribute("name") == False: raise Exception("Anonymous struct") self.nescType = xmlDefinition.getAttribute("name") self.size = int(xmlDefinition.getAttribute("size")[2:]) self._parseXMLFields(nescTypes, xmlDefinition) else : raise Exception("Illegal nescStruct constructor args") self.cType = self.nescType self.pythonType = self.nescType self.__initialized = True def __getattr__(self, name) : if self.__dict__.has_key("value") : if self.value.has_key(name) : if self.value[name].__class__ == nescType : return self.value[name].value else : return self.value[name] else : raise AttributeError("No such field \"%s\" in the nescStruct \"%s\"" % (name, self.nescType)) def __setattr__(self, name, value) : if not self.__dict__.has_key("_nescStruct__initialized") : self.__dict__[name] = value return if self.value.has_key(name) : if self.value[name].__class__ == nescType : self.value[name].value = value; else : self.value[name] = value; elif self.__dict__.has_key(name) : self.__dict__[name] = value else : raise AttributeError("No such field \"%s\" in the nescStruct \"%s\"" % (name, self.nescType)) def __repr__(self) : return "%s object at %s:\n\n\t%s" % (self.__class__, hex(id(self)), str(self)) def __str__(self) : """All fields and values as a readable string""" string = self.nescType + ": \n" for field in self.fields : string += "%30s : %s\n" % ( "%s %s" % (self.value[field["name"]].nescType, field["name"]), self.value[field["name"]].oneLineStr() ) return string def oneLineStr(self) : """A one-line representation of the struct""" return self.nescType def __deepcopy__(self, memo={}) : result = self.__class__() memo[id(self)] = result self._copyFields(result, memo) return result def _copyFields(self, other, memo=None) : other.size = self.size other.nescType = self.nescType other.cType = self.cType other.pythonType = self.pythonType if memo == None : other.value = deepcopy(self.value) other.fields = deepcopy(self.fields) else : other.value = deepcopy(self.value, memo) other.fields = deepcopy(self.fields, memo) other.__initialized = True def _parseXMLFields(self, nescTypes, xmlDefinition) : """Create a list of fields & values given a struct xml declaration.""" fields = [node for node in xmlDefinition.getElementsByTagName("field")] fields.sort( lambda A, B : A - B, lambda field: int(field.getAttribute("bit-offset")[2:]) ) for fieldDef in fields: field = {} field["name"] = fieldDef.getAttribute("name") field["bitOffset"] = int(fieldDef.getAttribute("bit-offset")[2:]) if fieldDef.hasAttribute("bit-size"): field["bitSize"] = int(fieldDef.getAttribute("bit-size")[2:]) elif fieldDef.hasAttribute("size"): field["bitSize"] = int(fieldDef.getAttribute("size")[2:])*8 self.fields.append(field) self.value[fieldDef.getAttribute("name")] = nescTypes.getTypeFromXML(fieldDef) #here's a weird bug in the nesc.xml generation where the "size" attribute #for packed structs is actually the size of the unpacked struct. if xmlDefinition.hasAttribute("packed") : self.size = self.packedSize() else: self.size = int(xmlDefinition.getAttribute("size")[2:]) def _parseNescTypeFields(self, fields) : """Create a list of fields & values given a tuple of fieldname,value sequences.""" self.size = 0 for fieldDef in fields: field = {} (field["name"],fType) = fieldDef field["bitOffset"] = self.size*8 field["bitSize"] = fType.size*8 self.fields.append(field) self.value[field["name"]] = fType self.size += fType.size def isType(self, xmlDefinition) : """returns 1 if the xml definition describes this type. Returns 0 otherwise.""" if xmlDefinition == None : return 0 child = getUniqueChild(xmlDefinition) if ( ( xmlDefinition.tagName == "struct" and xmlDefinition.getAttribute("name") == self.nescType) or ( xmlDefinition.tagName == "type-tag" and child != None and child.tagName == "struct-ref" and child.getAttribute("name") == self.nescType ) ) : return 1 else : return 0 def getBytes(self) : """Hexidecimal representation of struct""" # We have to be careful in here about: # 1. bit fields (ie. bitSize shorter than nominal type size) # 2. packing (ie. bits that are not part of any particular field) bits = "" for field in self.fields : for i in range(len(bits), field["bitOffset"]) : bits += "0" newBits = hex2bin(self.value[field["name"]].getBytes()) bits += newBits[-field["bitSize"]:] #the following loop is just type checking for bit fields. Can we do this on setattr? for i in range(len(newBits)-field["bitSize"]): if newBits[i] == "1": print "Bit-field type error: value of %s.%s being truncated" % (self.nescType, field["name"]) for i in range(len(bits), self.size*8) : bits += "0" bytes = bin2hex(bits) if len(bytes) != self.size: raise Exception("Byte conversion error: %s %d bytes to %d" % ( self.nescType, len(bytes), self.size)) return bytes def setBytes(self, bytes) : """Set all values using hexidecimal representation""" # We have to be careful in here about: # 1. bit fields (ie. bitSize shorter than nominal type size) # 2. packing (ie. bits that are not part of any particular field) if len(bytes) < self.size: raise Exception("Byte conversion error: %s %d bytes to %d" % (self.nescType, len(bytes), self.size) ) bits = hex2bin(bytes) for field in self.fields : newBits = "" for i in range(self.value[field["name"]].size*8) : newBits += "0" selectedBits=bits[field["bitOffset"]:field["bitOffset"]+field["bitSize"]] newBits = newBits[:-field["bitSize"]] + selectedBits newBytes = "" for i in range(self.value[field["name"]].size) : newBytes += '\x00' tmpBytes = bin2hex(newBits) newBytes = newBytes[:-len(tmpBytes)] + tmpBytes self.value[field["name"]].setBytes(newBytes); return bytes[self.size:] def packedSize(self) : if len(self.fields) == 0 : trueSize = 0 else : a,b,lastField = self._findLastNestedField() trueSize = (lastField["bitOffset"] + lastField["bitSize"]) /8 return trueSize def _findLastNestedField(self) : lastField = self parents = [] #find the last (possibly nested) field while issubclass(type(lastField), nescStruct) and len(lastField.fields) > 0 : parent = lastField lastFieldDef = parent.fields[-1] lastField = parent.value[lastFieldDef["name"]] parents.append( parent ) return (lastField, parents, lastFieldDef)class TosMsg ( nescStruct ) : """A python representation of a TosMsg. Is a nescStruct object. Can be used with pytos.comm.send, pytos.comm.register, pytos.comm.unregister. usage: msg = TosMsg(amType) msg = TosMsg(amType, nescStruct) msg = TosMsg(amType, <nescStruct constructor args>) print msg msg.field = X comm.send(msg) comm.register(msg, f) comm.unregister(msg, f) migMsg = msg.createMigMsg() msg.parseMigMsg(migMsg) """ def __init__(self, amType, *varargs): self.amType = amType self.parentMsg = None #if this is a nescStruct argument, make myself a clone of it if len(varargs) == 1 and issubclass(type(varargs[0]), nescStruct) : nescStruct._copyFields(varargs[0],self) #otherwise, make myself into a struct with the struct args elif len(varargs) >= 1: nescStruct.__init__(self, *varargs) def __deepcopy__(self, memo={}) : result = self.__class__(self.amType) memo[id(self)] = result self._copyFields(result, memo) result.parentMsg = deepcopy(self.parentMsg, memo) return result def getParentMsg(self, amOrName) : """This function will get the parent message with the amType or name specified""" if self.parentMsg == None : return None elif self.parentMsg.nescType == amOrName or self.parentMsg.amType == amOrName : return self.parentMsg else : return self.parentMsg.getParentMsg(amOrName) def createMigMsg(self) : """Returns a java BaseTOSMsg with same amType and length and with data payload of same bytes""" Message = jimport.net.tinyos.message.BaseTOSMsg msg = Message(self.size) msg.dataSet(unpack( str(self.size) + 'b', self.getBytes() ) ) msg.amTypeSet(self.amType)# msg.set_type( self.amType )# msg.set_length(self.size) return msg def parseMigMsg(self, msg) : """Takes a java BaseTOSMsg and creates TosMsg with same amType and length and with data payload of same bytes""" self.amType = msg.amType() data = list(msg.dataGet()) self.setBytes(pack(str(len(data)) + 'b', *data)) def __repr__(self) : return "%s object at %s:\n\n\t%s" % (self.__class__, hex(id(self)), str(self)) def __str__(self) : """All fields and values as a readable string""" return "TosMsg(am=%d) " % self.amType + nescStruct.__str__(self) def setBytes(self, bytes) : """Extend this msg to be longer, if necessary to accomodate extra data. This only happens if the last field is a nescArray of length 0. Unlike nescStructs, TosMsg objects are not nested recursively, so it is Ok to do this.""" if len(bytes) > self.size : #trueSize() : #print "there are more bytes than fit in this msg... trying to grow msg" lastField, parents,b = self._findLastNestedField() #see if it is an array of size 0 if type(lastField) == nescArray and lastField.len == 0 : #make it bigger #print "last field is nescArray[0]... growing" lastFieldSize = lastField.elementType.size numExtraBytes = len(bytes) - self.size #trueSize() if numExtraBytes % lastFieldSize == 0: requiredArraySize = int( numExtraBytes/lastFieldSize ) lastField = nescArray(requiredArraySize, lastField.elementType) #print "new size is %d" % numExtraBytes #and set it, changing the size of all parent structs parents.reverse() for parent in parents :# trueSize = parent.trueSize() parent.value[parent.fields[-1]["name"]] = lastField parent.fields[-1]["bitSize"] = lastField.size*8 parent.size = self.packedSize()# + lastField.size lastField = parent else: #print "last field is not nescArray[0]. Cannot grow. Ignoring extra data." pass #make sure everything worked out correctly and call parent's function if len(bytes) != self.size :#trueSize() : raise Exception("Incorrect number of bytes for TosMsg. Byte conversion error: %s %d bytes to %d" % ( self.nescType, len(bytes), self.size) ) #print "passing to child to set bytes." nescStruct.setBytes(self,bytes)def getUniqueChild(xmlDefinition) : child = None for childNode in xmlDefinition.childNodes : if childNode.nodeType == 1 : child = childNode break return childdef bin2hex(bits) : bytes = "" for i in range(0, len(bits), 8 ): bytes += pack('B',int(bits[i:i+8],2)) return bytesdef hex2bin(bytes) : bits = "" for i in range(len(bytes)) : val, = unpack('B',bytes[i]) for j in range(7,-1,-1): if val>= pow(2,j): bits += "1" val -= pow(2,j) else : bits += "0" return bitsdef TestAppTypes() : testRpc = appTypes('/home/kamin/tinyos-1.x/contrib/hood/apps/TestRpc/build/telosb/nesc.xml') print testRpc if __name__ == "__main__": TestAppTypes()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -