From 3eba1c72ef3ad9acf45ec538e535cd3c11a9dd74 Mon Sep 17 00:00:00 2001 From: kgv Date: Mon, 20 Jan 2020 18:09:32 +0300 Subject: [PATCH] 0031309: Data Exchange - RWObj_Reader fails to read mh03.obj with multi-line syntax Standard_ReadLineBuffer::SetMultilineMode() now accepts a flag to put gap space while joining lines, enabled by default. --- src/Standard/Standard_ReadLineBuffer.hxx | 64 ++++++++++++++++++------ tests/de_mesh/obj_read/multiline | 3 +- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/Standard/Standard_ReadLineBuffer.hxx b/src/Standard/Standard_ReadLineBuffer.hxx index 5e320df008..f9b9eb5dc4 100644 --- a/src/Standard/Standard_ReadLineBuffer.hxx +++ b/src/Standard/Standard_ReadLineBuffer.hxx @@ -27,6 +27,7 @@ public: Standard_ReadLineBuffer (size_t theMaxBufferSizeBytes) : myUseReadBufferLastStr(false), myIsMultilineMode (false), + myToPutGapInMultiline (true), myBufferPos (0), myBytesLastRead (0) { @@ -43,6 +44,7 @@ public: myReadBufferLastStr.clear(); myUseReadBufferLastStr = false; myIsMultilineMode = false; + myToPutGapInMultiline = true; myBufferPos = 0; myBytesLastRead = 0; } @@ -113,34 +115,44 @@ public: // read next line from myReadBuffer while (myBufferPos < myBytesLastRead) { - if (myReadBuffer[myBufferPos] == '\\' && myIsMultilineMode) + if (myIsMultilineMode + && myReadBuffer[myBufferPos] == '\\') { // multi-line syntax if (myBufferPos + 1 == myBytesLastRead - ||(myBufferPos + 2 == myBytesLastRead && myReadBuffer[myBufferPos + 1] == '\r')) + || (myBufferPos + 2 == myBytesLastRead + && myReadBuffer[myBufferPos + 1] == '\r')) { isMultiline = true; + if (myToPutGapInMultiline) + { + myReadBuffer[myBufferPos] = ' '; + if (myBufferPos + 1 != myBytesLastRead) + { + myReadBuffer[myBufferPos + 1] = ' '; + } + } } else if (myReadBuffer[myBufferPos + 1] == '\n' - ||(myReadBuffer[myBufferPos + 1] == '\r' && myReadBuffer[myBufferPos + 2] == '\n')) + ||(myReadBuffer[myBufferPos + 1] == '\r' + && myReadBuffer[myBufferPos + 2] == '\n')) { - if (myUseReadBufferLastStr) + size_t aBufferPos = myBufferPos; + myBufferPos = aBufferPos + (myReadBuffer[aBufferPos + 1] == '\r' ? 2 : 1); + if (myToPutGapInMultiline) { - myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos); - } - else - { - myReadBufferLastStr = std::vector(myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos); - myUseReadBufferLastStr = true; + myReadBuffer[aBufferPos] = ' '; + ++aBufferPos; } - if (myReadBuffer[myBufferPos + 1] == '\r') + if (myUseReadBufferLastStr) { - myBufferPos += 2; + myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + aBufferPos); } else { - myBufferPos += 1; + myReadBufferLastStr = std::vector(myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + aBufferPos); + myUseReadBufferLastStr = true; } aStartLinePos = myBufferPos + 1; @@ -229,11 +241,32 @@ public: return aResultLine; } - //! Returns TRUE when the Multiline Mode is on. + //! Returns TRUE when the Multiline Mode is on; FALSE by default. + //! Multiline modes joins several lines in file having \ at the end of line: + //! @code + //! Line starts here, \ // line continuation character without this comment + //! continues \ // line continuation character without this comment + //! and ends. + //! @endcode bool IsMultilineMode() const { return myIsMultilineMode; } + //! Put gap space while merging lines within multiline syntax, so that the following sample: + //! @code + //! 1/2/3\ // line continuation character without this comment + //! 4/5/6 + //! @endcode + //! Will become "1/2/3 4/5/6" when flag is TRUE, and "1/2/35/5/6" otherwise. + bool ToPutGapInMultiline() const { return myToPutGapInMultiline; } + //! Sets or unsets the multi-line mode. - void SetMultilineMode (bool theMultilineMode) { myIsMultilineMode = theMultilineMode; } + //! @param theMultilineMode [in] multiline mode flag + //! @param theToPutGap [in] put gap space while connecting lines (no gap otherwise) + void SetMultilineMode (bool theMultilineMode, + bool theToPutGap = true) + { + myIsMultilineMode = theMultilineMode; + myToPutGapInMultiline = theToPutGap; + } protected: @@ -263,6 +296,7 @@ protected: std::vector 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 + bool myToPutGapInMultiline; //!< Flag to put gap space while joining lines in multi-line syntax size_t myBufferPos; //!< Current position in myReadBuffer size_t myBytesLastRead; //!< The number of characters that were read last time from myReadBuffer. }; diff --git a/tests/de_mesh/obj_read/multiline b/tests/de_mesh/obj_read/multiline index d08d5cb292..baad78a59f 100644 --- a/tests/de_mesh/obj_read/multiline +++ b/tests/de_mesh/obj_read/multiline @@ -20,8 +20,7 @@ v 0 1 2\ __DUMMY__\ __DUMMY__ f 5 4 3 2 1 -f 7 8 \ -__SPLIT__ 9 10 6 +f 7 8__SPLIT__9 10 6 f 10 9 4 5 f 9 8 3 4 f 6 10 5 1