1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0030964: Data Exchange - use Standard_ReadLineBuffer within OBJ reader

Standard_ReadLineBuffer now supports a processing of the special multi-line case with \ at the end of the line.

Standard_RedLineBuffer was used to load Stl files
This commit is contained in:
mzernova
2019-09-17 16:05:05 +03:00
committed by bugmaster
parent 14a356b178
commit 51ee6a7dbb
4 changed files with 157 additions and 114 deletions

View File

@@ -26,6 +26,7 @@ public:
//! @param theMaxBufferSizeBytes the length of buffer to read (in bytes)
Standard_ReadLineBuffer (size_t theMaxBufferSizeBytes)
: myUseReadBufferLastStr(false),
myIsMultilineMode (false),
myBufferPos (0),
myBytesLastRead (0)
{
@@ -41,6 +42,7 @@ public:
{
myReadBufferLastStr.clear();
myUseReadBufferLastStr = false;
myIsMultilineMode = false;
myBufferPos = 0;
myBytesLastRead = 0;
}
@@ -71,6 +73,7 @@ public:
int64_t& theReadData)
{
char* aResultLine = NULL;
bool isMultiline = false;
theLineLength = 0;
theReadData = 0;
@@ -97,7 +100,7 @@ public:
if (myUseReadBufferLastStr)
{
theLineLength = myReadBufferLastStr.size();
aResultLine = myReadBufferLastStr.data();
aResultLine = &myReadBufferLastStr.front();
myUseReadBufferLastStr = false;
}
break;
@@ -110,9 +113,64 @@ public:
// read next line from myReadBuffer
while (myBufferPos < myBytesLastRead)
{
if (myReadBuffer[myBufferPos] == '\n')
if (myReadBuffer[myBufferPos] == '\\' && myIsMultilineMode)
{
isEndLineFound = true;
// multi-line syntax
if (myBufferPos + 1 == myBytesLastRead
||(myBufferPos + 2 == myBytesLastRead && myReadBuffer[myBufferPos + 1] == '\r'))
{
isMultiline = true;
}
else if (myReadBuffer[myBufferPos + 1] == '\n'
||(myReadBuffer[myBufferPos + 1] == '\r' && myReadBuffer[myBufferPos + 2] == '\n'))
{
if (myUseReadBufferLastStr)
{
myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
}
else
{
myReadBufferLastStr = std::vector<char>(myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
myUseReadBufferLastStr = true;
}
if (myReadBuffer[myBufferPos + 1] == '\r')
{
myBufferPos += 2;
}
else
{
myBufferPos += 1;
}
aStartLinePos = myBufferPos + 1;
}
}
else if (myReadBuffer[myBufferPos] == '\n')
{
if (!isMultiline)
{
isEndLineFound = true;
}
else if (myBufferPos == 1 && myReadBuffer[0] == '\r')
{
myReadBufferLastStr.erase (myReadBufferLastStr.end() - 1);
aStartLinePos += 2;
isMultiline = false;
}
else if (myBufferPos == 0)
{
aStartLinePos += 1;
if (myReadBufferLastStr[myReadBufferLastStr.size() - 1] == '\\')
{
myReadBufferLastStr.erase (myReadBufferLastStr.end() - 1);
}
else
{
myReadBufferLastStr.erase (myReadBufferLastStr.end() - 2, myReadBufferLastStr.end());
}
isMultiline = false;
}
}
++myBufferPos;
@@ -128,7 +186,7 @@ public:
myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
myUseReadBufferLastStr = false;
theLineLength = myReadBufferLastStr.size();
aResultLine = myReadBufferLastStr.data();
aResultLine = &myReadBufferLastStr.front();
}
else
{
@@ -137,7 +195,7 @@ public:
myReadBufferLastStr.clear();
}
theLineLength = myBufferPos - aStartLinePos;
aResultLine = myReadBuffer.data() + aStartLinePos;
aResultLine = &myReadBuffer.front() + aStartLinePos;
}
// make string null terminated by replacing '\n' or '\r' (before '\n') symbol to null character.
if (theLineLength > 1 && aResultLine[theLineLength - 2] == '\r')
@@ -156,14 +214,27 @@ public:
// save "unfinished" part of string to additional buffer
if (aStartLinePos != myBufferPos)
{
myReadBufferLastStr = std::vector<char>(myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
myUseReadBufferLastStr = true;
if (myUseReadBufferLastStr)
{
myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
}
else
{
myReadBufferLastStr = std::vector<char>(myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
myUseReadBufferLastStr = true;
}
}
}
}
return aResultLine;
}
//! Returns TRUE when the Multiline Mode is on.
bool IsMultilineMode() const { return myIsMultilineMode; }
//! Sets or unsets the multi-line mode.
void SetMultilineMode (bool theMultilineMode) { myIsMultilineMode = theMultilineMode; }
protected:
//! Read from stl stream.
@@ -172,7 +243,7 @@ protected:
size_t theLen,
size_t& theReadLen)
{
theReadLen = (size_t )theStream.read (myReadBuffer.data(), theLen).gcount();
theReadLen = (size_t )theStream.read (&myReadBuffer.front(), theLen).gcount();
return !theStream.bad();
}
@@ -182,7 +253,7 @@ protected:
size_t theLen,
size_t& theReadLen)
{
theReadLen = ::fread (myReadBuffer.data(), 1, theLen, theStream);
theReadLen = ::fread (&myReadBuffer.front(), 1, theLen, theStream);
return ::ferror (theStream) == 0;
}
@@ -191,6 +262,7 @@ protected:
std::vector<char> myReadBuffer; //!< Temp read buffer
std::vector<char> myReadBufferLastStr; //!< Part of last string of myReadBuffer
bool myUseReadBufferLastStr; //!< Flag to use myReadBufferLastStr during next line reading
bool myIsMultilineMode; //!< Flag to process of the special multi-line case at the end of the line
size_t myBufferPos; //!< Current position in myReadBuffer
size_t myBytesLastRead; //!< The number of characters that were read last time from myReadBuffer.
};