0031309: Data Exchange - RWObj_Reader fails to read mh03.obj with multi-line syntax
authorkgv <kgv@opencascade.com>
Mon, 20 Jan 2020 15:09:32 +0000 (18:09 +0300)
committerkgv <kgv@opencascade.com>
Tue, 21 Jan 2020 10:04:46 +0000 (13:04 +0300)
Standard_ReadLineBuffer::SetMultilineMode() now accepts a flag to put gap space while joining lines, enabled by default.

src/Standard/Standard_ReadLineBuffer.hxx
tests/de_mesh/obj_read/multiline

index 5e320df..f9b9eb5 100644 (file)
@@ -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)
-            {
-              myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
-            }
-            else
+            size_t aBufferPos = myBufferPos;
+            myBufferPos = aBufferPos + (myReadBuffer[aBufferPos + 1] == '\r' ? 2 : 1);
+            if (myToPutGapInMultiline)
             {
-              myReadBufferLastStr = std::vector<char>(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<char>(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<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
+  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.
 };
index d08d5cb..baad78a 100644 (file)
@@ -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