⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tossimnescdecls.py

📁 tinyos-2.x.rar
💻 PY
📖 第 1 页 / 共 2 页
字号:
      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")
      if xmlDefinition.getAttribute("size")[2:]:
        self.size = int(xmlDefinition.getAttribute("size")[2:])
      else:
        self.size = 0
      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 :  int(A.getAttribute("bit-offset")[2:]) - int(B.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()
    elif xmlDefinition.getAttribute("size")[2:]:
      self.size = int(xmlDefinition.getAttribute("size")[2:])
    else:
      self.size = 0
  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 = tinyos.message.Message()
        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 child

def bin2hex(bits) :
    bytes = ""
    for i in range(0, len(bits), 8 ):
        bytes += pack('B',int(bits[i:i+8],2))
    return bytes

def 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 bits


def 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 + -