optimization of getheader() using a dictionary

This commit is contained in:
Guido van Rossum 1996-05-28 23:08:25 +00:00
parent fdd45cb858
commit a13edb489b
1 changed files with 33 additions and 45 deletions

View File

@ -93,10 +93,11 @@ class Message:
# reproduce the header exactly as it appears in the file). # reproduce the header exactly as it appears in the file).
def readheaders(self): def readheaders(self):
self.dict = {}
self.unixfrom = '' self.unixfrom = ''
self.headers = list = [] self.headers = list = []
self.status = '' self.status = ''
headerseen = 0 headerseen = ""
firstline = 1 firstline = 1
while 1: while 1:
line = self.fp.readline() line = self.fp.readline()
@ -113,10 +114,16 @@ class Message:
elif headerseen and line[0] in ' \t': elif headerseen and line[0] in ' \t':
# It's a continuation line. # It's a continuation line.
list.append(line) list.append(line)
elif regex.match('^[!-9;-~]+:', line) >= 0: x = (self.dict[headerseen] + "\n " +
string.strip(line))
self.dict[headerseen] = string.strip(x)
elif ':' in line:
# It's a header line. # It's a header line.
list.append(line) list.append(line)
headerseen = 1 i = string.find(line, ':')
headerseen = string.lower(line[:i])
self.dict[headerseen] = string.strip(
line[i+1:])
else: else:
# It's not a header line; stop here. # It's not a header line; stop here.
if not headerseen: if not headerseen:
@ -198,22 +205,25 @@ class Message:
return string.joinfields(list, '') return string.joinfields(list, '')
# Going one step further: also strip leading and trailing # The normal interface: return a stripped version of the
# whitespace. # header value with a name, or None if it doesn't exist. This
# uses the dictionary version which finds the *last* such
# header.
def getheader(self, name): def getheader(self, name):
text = self.getrawheader(name) try:
if text == None: return self.dict[string.lower(name)]
except KeyError:
return None return None
return string.strip(text)
# Retrieve a single address from a header as a tuple, e.g. # Retrieve a single address from a header as a tuple, e.g.
# ('Guido van Rossum', 'guido@cwi.nl'). # ('Guido van Rossum', 'guido@cwi.nl').
def getaddr(self, name): def getaddr(self, name):
data = self.getheader(name) try:
if not data: data = self[name]
except KeyError:
return None, None return None, None
return parseaddr(data) return parseaddr(data)
@ -224,8 +234,9 @@ class Message:
# XXX This function is not really correct. The split # XXX This function is not really correct. The split
# on ',' might fail in the case of commas within # on ',' might fail in the case of commas within
# quoted strings. # quoted strings.
data = self.getheader(name) try:
if not data: data = self[name]
except KeyError:
return [] return []
data = string.splitfields(data, ',') data = string.splitfields(data, ',')
for i in range(len(data)): for i in range(len(data)):
@ -236,55 +247,32 @@ class Message:
# with time.mktime(). # with time.mktime().
def getdate(self, name): def getdate(self, name):
data = self.getheader(name) try:
if not data: data = self[name]
except KeyError:
return None return None
return parsedate(data) return parsedate(data)
# Access as a dictionary (only finds first header of each type): # Access as a dictionary (only finds *last* header of each type):
def __len__(self): def __len__(self):
types = {} return len(self.dict)
for line in self.headers:
if line[0] in string.whitespace: continue
i = string.find(line, ':')
if i > 0:
name = string.lower(line[:i])
types[name] = None
return len(types)
def __getitem__(self, name): def __getitem__(self, name):
value = self.getheader(name) return self.dict[string.lower(name)]
if value is None: raise KeyError, name
return value
def has_key(self, name): def has_key(self, name):
value = self.getheader(name) return self.dict.has_key(string.lower(name))
return value is not None
def keys(self): def keys(self):
types = {} return self.dict.keys()
for line in self.headers:
if line[0] in string.whitespace: continue
i = string.find(line, ':')
if i > 0:
name = line[:i]
key = string.lower(name)
types[key] = name
return types.values()
def values(self): def values(self):
values = [] return self.dict.values()
for name in self.keys():
values.append(self[name])
return values
def items(self): def items(self):
items = [] return self.dict.items()
for name in self.keys():
items.append(name, self[name])
return items