qgsdelimitedtextfile.cpp (QGIS-final-3_10_11) | : | qgsdelimitedtextfile.cpp (QGIS-final-3_10_12) | ||
---|---|---|---|---|
skipping to change at line 582 | skipping to change at line 582 | |||
{ | { | |||
mPosInBuffer = 0; | mPosInBuffer = 0; | |||
mBuffer = mStream->read( mMaxBufferSize ); | mBuffer = mStream->read( mMaxBufferSize ); | |||
} | } | |||
while ( !mBuffer.isEmpty() ) | while ( !mBuffer.isEmpty() ) | |||
{ | { | |||
// Identify position of \r , \n or \r\n | // Identify position of \r , \n or \r\n | |||
// We should rather use mStream->readLine(), but it fails to detect \r | // We should rather use mStream->readLine(), but it fails to detect \r | |||
// line endings. | // line endings. | |||
int eolPos = mBuffer.indexOf( '\r', mPosInBuffer ); | int eolPos = -1; | |||
int nextPos = 0; | ||||
if ( eolPos >= 0 ) | ||||
{ | { | |||
nextPos = eolPos + 1; | if ( mLineNumber == 0 ) | |||
// Check if there is a \n just afterwards | ||||
if ( eolPos + 1 < mBuffer.size() ) | ||||
{ | { | |||
if ( mBuffer[eolPos + 1] == '\n' ) | // For the first line we don't know yet the end of line character, so | |||
// manually scan for the first we find | ||||
const QChar *charBuffer = mBuffer.constData(); | ||||
const int bufferSize = mBuffer.size(); | ||||
for ( int pos = mPosInBuffer; pos < bufferSize; ++pos ) | ||||
{ | { | |||
nextPos = eolPos + 2; | if ( charBuffer[pos] == '\r' || charBuffer[pos] == '\n' ) | |||
{ | ||||
mFirstEOLChar = charBuffer[pos]; | ||||
eolPos = pos; | ||||
break; | ||||
} | ||||
} | } | |||
} | } | |||
else | else | |||
{ | { | |||
// If we are just at the end of the buffer, read an extra character | // Once we know the end of line character, use optimized indexOf() | |||
// from the stream | eolPos = mBuffer.indexOf( mFirstEOLChar, mPosInBuffer ); | |||
QString newChar = mStream->read( 1 ); | ||||
mBuffer += newChar; | ||||
if ( newChar == '\n' ) | ||||
{ | ||||
nextPos = eolPos + 2; | ||||
} | ||||
} | } | |||
} | } | |||
else | if ( eolPos >= 0 ) | |||
{ | { | |||
eolPos = mBuffer.indexOf( '\n', mPosInBuffer ); | int nextPos = eolPos + 1; | |||
if ( eolPos >= 0 ) | if ( mBuffer[eolPos] == '\r' ) | |||
{ | { | |||
nextPos = eolPos + 1; | // Check if there is a \n just afterwards | |||
if ( eolPos + 1 < mBuffer.size() ) | ||||
{ | ||||
if ( mBuffer[eolPos + 1] == '\n' ) | ||||
{ | ||||
nextPos = eolPos + 2; | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
// If we are just at the end of the buffer, read an extra character | ||||
// from the stream | ||||
QString newChar = mStream->read( 1 ); | ||||
mBuffer += newChar; | ||||
if ( newChar == '\n' ) | ||||
{ | ||||
nextPos = eolPos + 2; | ||||
} | ||||
} | ||||
} | } | |||
// Extract the current line from the buffer | ||||
buffer = mBuffer.mid( mPosInBuffer, eolPos - mPosInBuffer ); | ||||
// Update current position in buffer to be the one next to the end of | ||||
// line character(s) | ||||
mPosInBuffer = nextPos; | ||||
} | } | |||
if ( eolPos < 0 ) | else | |||
{ | { | |||
if ( mPosInBuffer == 0 ) | if ( mPosInBuffer == 0 ) | |||
{ | { | |||
// If our current position was the beginning of the buffer and we | // If our current position was the beginning of the buffer and we | |||
// didn't find any end of line character, then return the whole buffer | // didn't find any end of line character, then return the whole buffer | |||
// (to avoid unbounded line sizes) | // (to avoid unbounded line sizes) | |||
// and set the buffer to null so that we don't iterate any more. | // and set the buffer to null so that we don't iterate any more. | |||
buffer = mBuffer; | buffer = mBuffer; | |||
mBuffer = QString(); | mBuffer = QString(); | |||
} | } | |||
else | else | |||
{ | { | |||
// Read more bytes from file to have up to mMaxBufferSize characters | // Read more bytes from file to have up to mMaxBufferSize characters | |||
// in our buffer (after having subset it from mPosInBuffer) | // in our buffer (after having subset it from mPosInBuffer) | |||
mBuffer = mBuffer.mid( mPosInBuffer ); | mBuffer = mBuffer.mid( mPosInBuffer ); | |||
mBuffer += mStream->read( mMaxBufferSize - mBuffer.size() ); | mBuffer += mStream->read( mMaxBufferSize - mBuffer.size() ); | |||
mPosInBuffer = 0; | mPosInBuffer = 0; | |||
continue; | continue; | |||
} | } | |||
} | } | |||
else | ||||
{ | ||||
// Extract the current line from the buffer | ||||
buffer = mBuffer.mid( mPosInBuffer, eolPos - mPosInBuffer ); | ||||
// Update current position in buffer to be the one next to the end of | ||||
// line character(s) | ||||
mPosInBuffer = nextPos; | ||||
} | ||||
mLineNumber++; | mLineNumber++; | |||
if ( skipBlank && buffer.isEmpty() ) continue; | if ( skipBlank && buffer.isEmpty() ) continue; | |||
return RecordOk; | return RecordOk; | |||
} | } | |||
// Null string if at end of stream | // Null string if at end of stream | |||
return RecordEOF; | return RecordEOF; | |||
} | } | |||
bool QgsDelimitedTextFile::setNextLineNumber( long nextLineNumber ) | bool QgsDelimitedTextFile::setNextLineNumber( long nextLineNumber ) | |||
End of changes. 11 change blocks. | ||||
29 lines changed or deleted | 44 lines changed or added |