예제 #1
0
	def _parsetemplate(self, template):
		if isinstance(template, str): template = [template]
		# remove spaces from template
		tmplstr = re.sub('\s+', '', template[0])
		# if template is shorter than data, don't match
		data = self.data.rstrip('\0')
		if len(data) > len(tmplstr)/2: return False
		# pad data with zeroes to match with template
		data = self.data + '\0'*max(0, len(tmplstr)/2-len(self.data))
		# create template data with variables set to zero to be able to use getdata()
		tmpldatastr = re.sub('[^0-9a-f]', '0', tmplstr)
		tmpldata = ''.join([chr(int(tmpldatastr[i:i+2], 16)) for i in range(0, len(tmpldatastr), 2)])

		# determine fields and their nibble-offsets from template
		fields = []		# field names (or '0' for literal)
		tmploffsets = []	# offsets of fields from template
		lastchar = None
		for i in range(len(tmplstr)):
			curchar = tmplstr[i]
			if curchar in '0123456789abcdef': curchar = '0'
			if curchar != lastchar:
				fields.append(curchar)
				tmploffsets.append(i*4)
				lastchar = curchar
		tmploffsets.append(len(tmplstr)*4)

		# determine field boundaries, in the following order:
		# 1. specified start-offsets, if any
		#    1b. apply fixed-width fields with known start-offsets
		# 2. boundaries of template characters
		#    2b. apply fixed-width fields with known start-offsets
		# 3. boundaries of template literals
		offsets = [None] * (len(fields)+1)
		if len(template) > 1 and template[1]:
			for fchar,bitoffs in template[1].iteritems():
				offsets[fields.index(fchar)] = tmplstr.find(fchar)*4 + bitoffs
		self._apply_fixedwidth(fields, offsets)
		# boundaries of template characters
		for i in range(len(tmploffsets)-1):
			if offsets[i] is not None: continue
			if fields[i] == '0': continue
			offsets[i] = tmploffsets[i]
			self._apply_fixedwidth(fields, offsets)
		# boundaries of template literals
		for i in range(len(tmploffsets)):
			if offsets[i] is not None: continue
			offsets[i] = tmploffsets[i]
			self._apply_fixedwidth(fields, offsets)

		# now parse all fields
		fieldvalues={}
		for i in range(len(fields)):
			value = getbits(data, offsets[i], offsets[i+1])
			curchar = fields[i]
			if curchar == '0':
				# literal: check with template
				tmplvalue = getbits(tmpldata, offsets[i], offsets[i+1])
				if tmplvalue != value: return False
			else:
				# template variable: store
				fname, fchar, flen, ftype = self._field_by_char(curchar)
				try: fieldvalues[fname] = ftype(value, obj=self, width=(offsets[i+1]-offsets[i]+3)/4)
				except TypeError: fieldvalues[fname] = ftype(value)

		# everything is ok, incorporate fields
		self.__dict__.update(fieldvalues)
		return True
예제 #2
0
	def getbits(self, start, end):
		# return number at bit positions of data (0 is beginning)
		return getbits(self.data, start, end)