@@ -255,7 +255,7 @@ def charsUntil(self, characters, opposite = False):
255255 #optimizing
256256 #Possible improvements:
257257 # - use regexp to find characters that match the required character set
258- # - compute line positions in a single pass at the end
258+ # (with regexp cache since we do the same operations many many times)
259259 # - improve EOF handling for fewer if statements
260260
261261 if not self .queue :
@@ -266,13 +266,6 @@ def charsUntil(self, characters, opposite = False):
266266
267267 i = 0
268268 while (self .queue [i ] in characters ) == opposite :
269- #Working out positions like this really sucks
270- if self .queue [i ] == '\n ' :
271- self .lineLengths .append (self .col )
272- self .line += 1
273- self .col = 0
274- else :
275- self .col += 1
276269 i += 1
277270 if i == len (self .queue ):
278271 self .readChunk ()
@@ -281,6 +274,32 @@ def charsUntil(self, characters, opposite = False):
281274 break
282275
283276 rv = u"" .join (self .queue [:i ])
277+
278+ #Calculate where we now are in the stream
279+ #One possible optimisation would be to store all read characters and
280+ #Calculate this on an as-needed basis (perhaps flushing the read data
281+ #every time we read a new chunk) rather than once per call here and
282+ #in .char()
283+ lines = rv .split ("\n " )
284+
285+ if lines :
286+ #Add number of lines passed onto positon
287+ oldCol = self .col
288+ self .line += len (lines )- 1
289+ if len (lines ) > 1 :
290+ self .col = len (lines [- 1 ])
291+ else :
292+ self .col += len (lines [0 ])
293+
294+ if self .lineLengths and oldCol > 0 :
295+ self .lineLengths [- 1 ] += len (lines [0 ])
296+ lines = lines [1 :- 1 ]
297+ else :
298+ lines = lines [:- 1 ]
299+
300+ for line in lines :
301+ self .lineLengths .append (len (line ))
302+
284303 self .queue = self .queue [i :]
285304
286305 return rv
0 commit comments