connectivity/source/drivers/flat/ETable.cxx |   26 +++++++++++++++-----------
 connectivity/source/inc/flat/ETable.hxx     |    1 +
 2 files changed, 16 insertions(+), 11 deletions(-)

New commits:
commit 50c64dc7b89da8f40c71e2ff6d3697a9b6b55442
Author: Damjan Jovanovic <[email protected]>
Date:   Sun Apr 3 15:02:59 2016 +0000

    #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

diff --git a/connectivity/source/drivers/flat/ETable.cxx 
b/connectivity/source/drivers/flat/ETable.cxx
index 47f5c52..1620b64 100644
--- a/connectivity/source/drivers/flat/ETable.cxx
+++ b/connectivity/source/drivers/flat/ETable.cxx
@@ -72,26 +72,26 @@ void OFlatTable::fillColumns(const 
::com::sun::star::lang::Locale& _aLocale)
 
     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::sun::star::lang::Locale& _aLocale)
         }
         ++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(IResultSetHelper::Movement 
eCursorPosition, sal_Int
 // 
-----------------------------------------------------------------------------
 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", "[email protected]", 
"OFlatTable::readLine" );
     const rtl_TextEncoding nEncoding = m_pConnection->getTextEncoding();
-    m_pFileStream->ReadByteStringLine(m_aCurrentLine,nEncoding);
+    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)
     _rnCurrentPos = m_pFileStream->Tell();
     return sal_True;
 }
-
diff --git a/connectivity/source/inc/flat/ETable.hxx 
b/connectivity/source/inc/flat/ETable.hxx
index 0042e2e..b9f2304 100644
--- a/connectivity/source/inc/flat/ETable.hxx
+++ b/connectivity/source/inc/flat/ETable.hxx
@@ -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);
_______________________________________________
Libreoffice-commits mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to