import string
def textopen(pathOrFile, mode='r'):
if mode == 'r':
return _TextFileLinefeedAdaptor(pathOrFile)
elif mode == 'r+':
try:
exception = NotImplementedError
except:
exception = Exception
raise exception, "'r+' mode is not implemented"
else:
return open(pathOrFile)
class _TextFileLinefeedAdaptor:
BLOCK_SIZE = 512
def __init__(self, pathOrFile):
import types
file = pathOrFile
if isinstance(file, types.StringType):
file = open(file, "rb")
self.file = file
self.buffer = None
def __getattr__(self, name):
if name in ('closed', 'mode', 'name', 'softspace'):
return getattr(self.file, name)
else:
raise AttributeError, name
def close(self):
self.file.close()
def readline(self):
buffer = self.buffer
if not buffer:
buffer = self.file.read(self.BLOCK_SIZE)
if not buffer:
return ''
crpos = string.find(buffer, '\r')
lfpos = string.find(buffer, '\n')
if max(crpos, lfpos) < 0:
self.buffer = None
return buffer + self.readline()
if lfpos < 0 or 0 <= crpos < lfpos:
line = buffer[:crpos] + '\n'
otherchar = '\n'
nextpos = crpos + 1
else:
line = buffer[:lfpos + 1]
otherchar = '\r'
nextpos = lfpos + 1
if nextpos == len(buffer):
buffer = self.file.read(self.BLOCK_SIZE)
nextpos = 0
if buffer and buffer[nextpos] == otherchar:
nextpos = nextpos + 1
self.buffer = buffer[nextpos:]
return line
def readlines(self):
lines = []
while 1:
line = self.readline()
if line == '':
break
lines.append(line)
return lines
def read(self, length=None):
self.seek(self.tell())
if length:
return self.file.read(length)
else:
self.file.read()
def rewind(self):
self.seek(0)
def seek(self, position):
self.file.seek(position)
self.buffer = None
def tell(self):
return self.file.tell() - len(self.buffer or "")
def _test():
_testlength(1)
for index in range(-2, 3):
_testlength(_TextFileLinefeedAdaptor.BLOCK_SIZE + index)
def _testlength(length):
import tempfile
import string
lines = []
for line in '1', '2', '3':
lines.append(line * length)
separators = {'UNIX': '\n', 'MacOS': '\r', 'DOS': '\n\r'}
for separator in separators.keys():
filename = tempfile.mktemp()
try:
file = open(filename, 'wb')
# leave the separator off the last line, to test that case too
file.write(string.join(lines, separators[separator]))
file.close()
file = textopen(filename, 'r')
for index in range(len(lines)):
expected = lines[index]
if index != len(lines) - 1:
expected = expected + '\n'
actual = file.readline()
if expected != actual:
print 'Platform %s:\n expected: %s\n read: %s' % (separator, `expected`, `actual`)
finally:
try:
file.close()
except:
pass
import os
os.remove(filename)