def ilines(source_iterable):
'''yield lines as in universal-newlines from a stream of data blocks'''
tail = ''
for block in source_iterable:
if not block:
continue
if tail.endswith('\015'):
yield tail[:-1] + '\012'
if block.startswith('\012'):
pos = 1
else:
tail = ''
else:
pos = 0
try:
while True: # While we are finding LF.
npos = block.index('\012', pos) + 1
try:
rend = npos - 2
rpos = block.index('\015', pos, rend)
if pos:
yield block[pos : rpos] + '\n'
else:
yield tail + block[:rpos] + '\n'
pos = rpos + 1
while True: # While CRs 'inside' the LF
rpos = block.index('\015', pos, rend)
yield block[pos : rpos] + '\n'
pos = rpos + 1
except ValueError:
pass
if '\015' == block[rend]:
if pos:
yield block[pos : rend] + '\n'
else:
yield tail + block[:rend] + '\n'
elif pos:
yield block[pos : npos]
else:
yield tail + block[:npos]
pos = npos
except ValueError:
pass
# No LFs left in block. Do all but final CR (in case LF)
try:
while True:
rpos = block.index('\015', pos, -1)
if pos:
yield block[pos : rpos] + '\n'
else:
yield tail + block[:rpos] + '\n'
pos = rpos + 1
except ValueError:
pass
if pos:
tail = block[pos:]
else:
tail += block
if tail:
yield tail