@@ -337,14 +337,30 @@ void Scanner::SetInputStream(SourcePtr stream)
337337
338338bool Scanner::SetInputStream (SourcePtr stream, const Bookmark& bookmark)
339339{
340- mpSource = stream;
340+ if ((mpSource == stream) && (bookmark.offset >= mBase ) &&
341+ ((bookmark.offset - mBase ) < (mpBufferEnd - maBuffer)))
342+ {
343+ // Bookmark is already loaded in the buffer.
344+ // Just advance/rewind the next character accordingly.
345+ mpNextChar = maBuffer + (bookmark.offset - mBase );
346+ }
347+ else
348+ {
349+ // Not in buffer at the moment.
350+
351+ // Make sure we have the right stream.
352+ mpSource = stream;
353+
354+ // Refill the buffer.
355+ mEndOfStream = !mpSource->seekg (bookmark.offset );
356+ mBase = mpSource->tellg ();
357+ mpBufferEnd = maBuffer;
358+ mpNextChar = maBuffer;
359+ if (!mEndOfStream )
360+ RefillBuffer ();
361+ }
341362
342- mEndOfStream = !mpSource->seekg (bookmark.offset );
343- mBase = mpSource->tellg ();
344- mpBufferEnd = maBuffer;
345- mpNextChar = maBuffer;
346- if (!mEndOfStream )
347- RefillBuffer ();
363+ // Set the scanner state back to when the bookmark was created.
348364
349365 SetStringEncoding (bookmark.stringEncoding );
350366
@@ -457,8 +473,10 @@ bool Scanner::GetNextDirective(Lexeme& lexeme)
457473
458474 while (!mEndOfStream )
459475 {
460- // Skip over any whitespace (including blank lines).
461- while (IsWhitespace (*mpNextChar))
476+ // Skip over pretty much anything, except stuff that may
477+ // invalidate the lexeme we are looking for.
478+ while (IsWhitespace (*mpNextChar) ||
479+ ((*mpNextChar != ' "' ) && (*mpNextChar != ' /' ) && (*mpNextChar != ' #' )))
462480 {
463481 if (!Advance ())
464482 return false ;
@@ -476,7 +494,7 @@ bool Scanner::GetNextDirective(Lexeme& lexeme)
476494 else if (*mpNextChar == ' /' )
477495 {
478496 // Either division operator or start of comment.
479- if (!CopyAndAdvance (lexeme ))
497+ if (!Advance ( ))
480498 return false ;
481499 if (*mpNextChar == ' /' )
482500 {
@@ -491,18 +509,14 @@ bool Scanner::GetNextDirective(Lexeme& lexeme)
491509 }
492510 continue ; // Not a lexeme we are looking for. Rinse & repeat.
493511 }
494- else if (*mpNextChar == ' # ' )
512+ else
495513 {
514+ POV_PARSER_ASSERT (*mpNextChar == ' #' );
496515 // Found what we've been looking for.
497516 lexeme.category = Lexeme::Category::kOther ;
498517 (void )CopyAndAdvance (lexeme);
499518 return true ;
500519 }
501- else
502- {
503- if (!Advance ())
504- return false ;
505- }
506520 }
507521
508522 return false ;
0 commit comments