0001
0002
0003"""Utility functions for Kid."""
0004
0005__revision__ = "$Rev: 492 $"
0006__date__ = "$Date: 2007-07-06 21:38:45 -0400 (Fri, 06 Jul 2007) $"
0007__author__ = "Ryan Tomayko (rtomayko@gmail.com)"
0008__copyright__ = "Copyright 2004-2005, Ryan Tomayko"
0009__license__ = "MIT <http://www.opensource.org/licenses/mit-license.php>"
0010
0011
0012from urllib import splittype
0013
0014
0015class QuickTextReader(object):
0016
0017 def __init__(self, text):
0018 self.text = text
0019 self.len = len(self.text)
0020 self.pos = 0
0021 self.lines = None
0022
0023 def __iter__(self):
0024 while 1:
0025 if self.lines is None:
0026 self.lines = self.text.splitlines(True)
0027 if not self.lines:
0028 break
0029 yield self.lines.pop(0)
0030
0031 def close(self):
0032 self.text = None
0033 self.pos = self.len = 0
0034 self.lines = None
0035
0036 def read(self, size=None):
0037 if size is not None:
0038 try:
0039 size = int(size)
0040 except:
0041 size = None
0042 else:
0043 if not 0 <= size < self.len:
0044 size = None
0045 pos = self.pos
0046 if size is None:
0047 self.pos = self.len
0048 return self.text[pos:]
0049 else:
0050 self.pos += size
0051 if self.pos > self.len:
0052 self.pos = self.len
0053 return self.text[pos:self.pos]
0054
0055 def seek(self, offset, whence=0):
0056 if whence:
0057 if whence == 2:
0058 self.pos = self.len - offset
0059 else:
0060 self.pos += offset
0061 else:
0062 self.pos = offset
0063 self.lines = None
0064 if self.pos < 0:
0065 self.pos = 0
0066 elif self.pos > self.len:
0067 self.pos = self.len
0068
0069 def tell(self):
0070 return self.pos
0071
0072 def next(self):
0073 if not self.lineno:
0074 self.lines = self.splitlines(True)
0075 self.lineno += 1
0076 if not self.lines:
0077 raise StopIteration
0078 return self.lines.pop(0)
0079
0080def xml_sniff(text):
0081 """Sniff text to see if it looks like XML.
0082
0083 Return True if text looks like XML, otherwise return False.
0084
0085 """
0086 for x in text:
0087 if x in '\t\r\n ':
0088 continue
0089 elif x == '<':
0090 return True
0091 else:
0092 return False
0093
0094def open_resource(uri, mode='rb'):
0095 """Generic resource opener."""
0096 scheme, rest = splittype(uri)
0097 if not scheme or (len(scheme) == 1 and rest.startswith('\\')):
0098 return open(uri, mode)
0099 else:
0100 import urllib2
0101 return urllib2.urlopen(uri)
0102
0103def get_expat_error(error):
0104 """Return text showing the position of an Expat error."""
0105 source, lineno, offset = error.source, error.lineno, error.offset
0106 if lineno < 1:
0107 lineno = 1
0108 offset = 0
0109 source.seek(0)
0110 nlines = 0
0111 for line in source:
0112 lineno -= 1
0113 nlines += 1
0114 if not lineno:
0115 break
0116 else:
0117 offset = 0
0118 if nlines:
0119 if nlines == 1:
0120 if line.startswith('\xef\xbb\xbf'):
0121 line = line[3:]
0122 if line:
0123 if offset < 0:
0124 offset = 0
0125 elif offset > len(line):
0126 offset = len(line)
0127 if offset > 75:
0128 if len(line) - offset > 37:
0129 line = line[offset-38:offset+38]
0130 offset = 38
0131 else:
0132 offset -= len(line) - 76
0133 line = line[-76:]
0134 else:
0135 line = line[:76]
0136 if line:
0137 line = '%s\n%%%ds\n' % (line.rstrip(), offset + 1)
0138 line = line % '^'
0139 return line