You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by da...@apache.org on 2016/04/03 17:03:00 UTC

svn commit: r1737591 - in /openoffice/trunk/main/connectivity/source: drivers/flat/ETable.cxx inc/flat/ETable.hxx

Author: damjan
Date: Sun Apr  3 15:02:59 2016
New Revision: 1737591

URL: http://svn.apache.org/viewvc?rev=1737591&view=rev
Log:
#i122754# Base does not properly parse CSV files as per RFC-4180 (while
Calc does)

The flat file driver, in file
main/connectivity/source/drivers/flat/ETable.cxx, method
OFlatTable::fillColumns(), which reads lines to initialize columns,
assumes fields in the header and the first few lines never continue onto
the next line(s). This causes truncation of columns when they do.

Read all lines using the readLine() method instead of
SvStream::ReadByteStringLine(), which takes overflow onto next lines into
account. Also implement a new version of readLine() which allows reading
into an arbitrary string, as opposed to m_aCurrentLine only.

Patch by: me


Modified:
    openoffice/trunk/main/connectivity/source/drivers/flat/ETable.cxx
    openoffice/trunk/main/connectivity/source/inc/flat/ETable.hxx

Modified: openoffice/trunk/main/connectivity/source/drivers/flat/ETable.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/connectivity/source/drivers/flat/ETable.cxx?rev=1737591&r1=1737590&r2=1737591&view=diff
==============================================================================
--- openoffice/trunk/main/connectivity/source/drivers/flat/ETable.cxx (original)
+++ openoffice/trunk/main/connectivity/source/drivers/flat/ETable.cxx Sun Apr  3 15:02:59 2016
@@ -72,26 +72,26 @@ void OFlatTable::fillColumns(const ::com
 
 	QuotedTokenizedString aHeaderLine;
 	OFlatConnection* pConnection = (OFlatConnection*)m_pConnection;
-    const rtl_TextEncoding nEncoding = m_pConnection->getTextEncoding();
     const sal_Bool bHasHeaderLine = pConnection->isHeaderLine();
+    sal_Int32 nCurPos;
 	if ( bHasHeaderLine )
 	{
 		while(bRead && !aHeaderLine.Len())
 		{
-			bRead = m_pFileStream->ReadByteStringLine(aHeaderLine,nEncoding);
+			bRead = readLine(aHeaderLine, nCurPos);
 		}
         m_nStartRowFilePos = m_pFileStream->Tell();
 	}
 
 	// read first row
 	QuotedTokenizedString aFirstLine;
-	bRead = m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding);
+	bRead = readLine(aFirstLine, nCurPos);
 
 	if ( !bHasHeaderLine || !aHeaderLine.Len())
 	{
 		while(bRead && !aFirstLine.Len())
 		{
-			bRead = m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding);
+			bRead = readLine(aFirstLine, nCurPos);
 		}
 		// use first row as headerline because we need the number of columns
 		aHeaderLine = aFirstLine;
@@ -155,7 +155,7 @@ void OFlatTable::fillColumns(const ::com
 	    }
         ++nRowCount;
     }
-    while(nRowCount < nMaxRowsToScan && m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding) && !m_pFileStream->IsEof());
+    while(nRowCount < nMaxRowsToScan && readLine(aFirstLine,nCurPos) && !m_pFileStream->IsEof());
 
     for (xub_StrLen i = 0; i < nFieldCount; i++)
     {
@@ -895,21 +895,26 @@ sal_Bool OFlatTable::seekRow(IResultSetH
 // -----------------------------------------------------------------------------
 sal_Bool OFlatTable::readLine(sal_Int32& _rnCurrentPos)
 {
+    return readLine(m_aCurrentLine, _rnCurrentPos);
+}
+// -----------------------------------------------------------------------------
+sal_Bool OFlatTable::readLine(QuotedTokenizedString& line, sal_Int32& _rnCurrentPos)
+{
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::readLine" );
     const rtl_TextEncoding nEncoding = m_pConnection->getTextEncoding();
-    m_pFileStream->ReadByteStringLine(m_aCurrentLine,nEncoding);
-	if (m_pFileStream->IsEof())
-		return sal_False;
+    m_pFileStream->ReadByteStringLine(line,nEncoding);
+    if (m_pFileStream->IsEof())
+        return sal_False;
 
-    QuotedTokenizedString sLine = m_aCurrentLine; // check if the string continues on next line
+    QuotedTokenizedString sLine = line; // check if the string continues on next line
     while( (sLine.GetString().GetTokenCount(m_cStringDelimiter) % 2) != 1 )
     {
         m_pFileStream->ReadByteStringLine(sLine,nEncoding);
         if ( !m_pFileStream->IsEof() )
         {
-            m_aCurrentLine.GetString().Append('\n');
-            m_aCurrentLine.GetString() += sLine.GetString();
-            sLine = m_aCurrentLine;
+            line.GetString().Append('\n');
+            line.GetString() += sLine.GetString();
+            sLine = line;
         }
         else
             break;
@@ -917,4 +922,3 @@ sal_Bool OFlatTable::readLine(sal_Int32&
     _rnCurrentPos = m_pFileStream->Tell();
     return sal_True;
 }
-

Modified: openoffice/trunk/main/connectivity/source/inc/flat/ETable.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/connectivity/source/inc/flat/ETable.hxx?rev=1737591&r1=1737590&r2=1737591&view=diff
==============================================================================
--- openoffice/trunk/main/connectivity/source/inc/flat/ETable.hxx (original)
+++ openoffice/trunk/main/connectivity/source/inc/flat/ETable.hxx Sun Apr  3 15:02:59 2016
@@ -64,6 +64,7 @@ namespace connectivity
 			void fillColumns(const ::com::sun::star::lang::Locale& _aLocale);
 			sal_Bool CreateFile(const INetURLObject& aFile, sal_Bool& bCreateMemo);
             sal_Bool readLine(sal_Int32& _rnCurrentPos);
+            sal_Bool readLine(QuotedTokenizedString& line, sal_Int32& _rnCurrentPos);
             void impl_fillColumnInfo_nothrow(QuotedTokenizedString& aFirstLine,xub_StrLen& nStartPosFirstLine,xub_StrLen& nStartPosFirstLine2
                                              ,sal_Int32& io_nType,sal_Int32& io_nPrecisions,sal_Int32& io_nScales,String& o_sTypeName
                                              ,const sal_Unicode cDecimalDelimiter,const sal_Unicode cThousandDelimiter,const CharClass& aCharClass);