/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"

#include <ctype.h>
#include "flat/ETable.hxx"
#include <com/sun/star/sdbc/ColumnValue.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/ucb/XContentAccess.hpp>
#include <svl/converter.hxx>
#include "flat/EConnection.hxx"
#include "flat/EColumns.hxx"
#include <osl/thread.h>
#include <tools/config.hxx>
#include <comphelper/sequence.hxx>
#include <svl/zforlist.hxx>
#include <rtl/math.hxx>
#include <stdio.h>		//sprintf
#include <comphelper/extract.hxx>
#include <comphelper/numbers.hxx>
#include "flat/EDriver.hxx"
#include <com/sun/star/util/NumberFormat.hpp>
#include <unotools/configmgr.hxx>
#include <i18npool/mslangid.hxx>
#include "connectivity/dbconversion.hxx"
#include <comphelper/types.hxx>
#include "file/quotedstring.hxx"
#include <unotools/syslocale.hxx>
#include <rtl/logfile.hxx>

using namespace ::comphelper;
using namespace connectivity;
using namespace connectivity::flat;
using namespace connectivity::file;
using namespace ::cppu;
using namespace utl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;

// -------------------------------------------------------------------------
void OFlatTable::fillColumns(const ::com::sun::star::lang::Locale& _aLocale)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::fillColumns" );
	sal_Bool bRead = sal_True;

	QuotedTokenizedString aHeaderLine;
	OFlatConnection* pConnection = (OFlatConnection*)m_pConnection;
    const rtl_TextEncoding nEncoding = m_pConnection->getTextEncoding();
    const sal_Bool bHasHeaderLine = pConnection->isHeaderLine();
	if ( bHasHeaderLine )
	{
		while(bRead && !aHeaderLine.Len())
		{
			bRead = m_pFileStream->ReadByteStringLine(aHeaderLine,nEncoding);
		}
        m_nStartRowFilePos = m_pFileStream->Tell();
	}

	// read first row
	QuotedTokenizedString aFirstLine;
	bRead = m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding);

	if ( !bHasHeaderLine || !aHeaderLine.Len())
	{
		while(bRead && !aFirstLine.Len())
		{
			bRead = m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding);
		}
		// use first row as headerline because we need the number of columns
		aHeaderLine = aFirstLine;
	}
	// column count
	const xub_StrLen nFieldCount = aHeaderLine.GetTokenCount(m_cFieldDelimiter,m_cStringDelimiter);

	if(!m_aColumns.isValid())
		m_aColumns = new OSQLColumns();
	else
		m_aColumns->get().clear();

	m_aTypes.clear();
	m_aPrecisions.clear();
	m_aScales.clear();
	// reserve some space
	m_aColumns->get().reserve(nFieldCount+1);
    m_aTypes.assign(nFieldCount+1,DataType::SQLNULL);
	m_aPrecisions.assign(nFieldCount+1,-1);
	m_aScales.assign(nFieldCount+1,-1);

	const sal_Bool bCase = m_pConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers();
	CharClass aCharClass(pConnection->getDriver()->getFactory(),_aLocale);
	// read description
	const sal_Unicode cDecimalDelimiter  = pConnection->getDecimalDelimiter();
	const sal_Unicode cThousandDelimiter = pConnection->getThousandDelimiter();
	String aColumnName;
	::rtl::OUString aTypeName;
	::comphelper::UStringMixEqual aCase(bCase);
    ::std::vector<String> aColumnNames,m_aTypeNames;
    m_aTypeNames.resize(nFieldCount);
    const sal_Int32 nMaxRowsToScan = pConnection->getMaxRowsToScan();
    sal_Int32 nRowCount = 0;
    do
    {
	    xub_StrLen nStartPosHeaderLine = 0; // use for eficient way to get the tokens
	    xub_StrLen nStartPosFirstLine = 0; // use for eficient way to get the tokens
	    xub_StrLen nStartPosFirstLine2 = 0;
	    for (xub_StrLen i = 0; i < nFieldCount; i++)
	    {
            if ( nRowCount == 0)
            {
		        if ( bHasHeaderLine )
		        {
			        aHeaderLine.GetTokenSpecial(aColumnName,nStartPosHeaderLine,m_cFieldDelimiter,m_cStringDelimiter);
			        if ( !aColumnName.Len() )
			        {
				        aColumnName = 'C';
				        aColumnName += String::CreateFromInt32(i+1);
			        }
		        }
		        else
		        {
			        // no column name so ...
			        aColumnName = 'C';
			        aColumnName += String::CreateFromInt32(i+1);
		        }
                aColumnNames.push_back(aColumnName);
            }
            impl_fillColumnInfo_nothrow(aFirstLine,nStartPosFirstLine,nStartPosFirstLine2,m_aTypes[i],m_aPrecisions[i],m_aScales[i],m_aTypeNames[i],cDecimalDelimiter,cThousandDelimiter,aCharClass);
	    }
        ++nRowCount;
    }
    while(nRowCount < nMaxRowsToScan && m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding) && !m_pFileStream->IsEof());

    for (xub_StrLen i = 0; i < nFieldCount; i++)
    {
        // check if the columname already exists
	    String aAlias(aColumnNames[i]);
	    OSQLColumns::Vector::const_iterator aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase);
	    sal_Int32 nExprCnt = 0;
	    while(aFind != m_aColumns->get().end())
	    {
		    (aAlias = aColumnNames[i]) += String::CreateFromInt32(++nExprCnt);
		    aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase);
	    }

	    sdbcx::OColumn* pColumn = new sdbcx::OColumn(aAlias,m_aTypeNames[i],::rtl::OUString(),::rtl::OUString(),
											    ColumnValue::NULLABLE,
                                                m_aPrecisions[i],
											    m_aScales[i],
											    m_aTypes[i],
											    sal_False,
											    sal_False,
											    sal_False,
											    bCase);
	    Reference< XPropertySet> xCol = pColumn;
	    m_aColumns->get().push_back(xCol);
    }
	m_pFileStream->Seek(m_nStartRowFilePos);
}
void OFlatTable::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)
{
    if ( io_nType != DataType::VARCHAR )
    {
        sal_Bool bNumeric = io_nType == DataType::SQLNULL || io_nType == DataType::DOUBLE || io_nType == DataType::DECIMAL || io_nType == DataType::INTEGER;
	    sal_uLong  nIndex = 0;

        if ( bNumeric )
        {
	        // first without fielddelimiter
	        String aField;
	        aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine,m_cFieldDelimiter,'\0');
	        if (aField.Len() == 0 ||
		        (m_cStringDelimiter && m_cStringDelimiter == aField.GetChar(0)))
	        {
		        bNumeric = sal_False;
                if ( m_cStringDelimiter != '\0' )
			        aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
                else
		            nStartPosFirstLine2 = nStartPosFirstLine;
	        }
	        else
	        {
		        String aField2;
		        if ( m_cStringDelimiter != '\0' )
			        aFirstLine.GetTokenSpecial(aField2,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
		        else
			        aField2 = aField;

		        if (aField2.Len() == 0)
		        {
			        bNumeric = sal_False;
		        }
		        else
		        {
			        bNumeric = sal_True;
			        xub_StrLen nDot = 0;
                    xub_StrLen nDecimalDelCount = 0;
                    xub_StrLen nSpaceCount = 0;
			        for (xub_StrLen j = 0; j < aField2.Len(); j++)
			        {
				        const sal_Unicode c = aField2.GetChar(j);
                        if ( j == nSpaceCount && m_cFieldDelimiter != 32 && c == 32 )
                        {
                            ++nSpaceCount;
                            continue;
                        }
				        // nur Ziffern und Dezimalpunkt und Tausender-Trennzeichen?
				        if ( ( !cDecimalDelimiter  || c != cDecimalDelimiter )  &&
					         ( !cThousandDelimiter || c != cThousandDelimiter ) &&
					        !aCharClass.isDigit(aField2,j)                      &&
                            ( j != 0 || (c != '+' && c != '-' ) ) )
				        {
				            bNumeric = sal_False;
				            break;
				        }
				        if (cDecimalDelimiter && c == cDecimalDelimiter)
				        {
					        io_nPrecisions = 15; // we have an decimal value
					        io_nScales = 2;
                            ++nDecimalDelCount;
				        } // if (cDecimalDelimiter && c == cDecimalDelimiter)
                        if ( c == '.' )
                            ++nDot;
			        }

			        if (nDecimalDelCount > 1 || nDot > 1 ) // if there is more than one dot it isn't a number
				        bNumeric = sal_False;
			        if (bNumeric && cThousandDelimiter)
			        {
				        // Ist der Trenner richtig angegeben?
				        const String aValue = aField2.GetToken(0,cDecimalDelimiter);
				        for (sal_Int32 j = aValue.Len() - 4; j >= 0; j -= 4)
				        {
					        const sal_Unicode c = aValue.GetChar(static_cast<sal_uInt16>(j));
					        // nur Ziffern und Dezimalpunkt und Tausender-Trennzeichen?
					        if (c == cThousandDelimiter && j)
						        continue;
					        else
					        {
						        bNumeric = sal_False;
						        break;
					        }
				        }
			        }

                    // jetzt koennte es noch ein Datumsfeld sein
			        if (!bNumeric)
			        {
				        try
				        {
					        nIndex = m_xNumberFormatter->detectNumberFormat(::com::sun::star::util::NumberFormat::ALL,aField2);
				        }
				        catch(Exception&)
				        {
				        }
			        }
		        }
	        }
        }
        else if ( io_nType == DataType::DATE || io_nType == DataType::TIMESTAMP || io_nType == DataType::TIME)
        {
            String aField;
	        aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine,m_cFieldDelimiter,'\0');
            if (aField.Len() == 0 ||
		        (m_cStringDelimiter && m_cStringDelimiter == aField.GetChar(0)))
	        {
            }
            else
            {
                String aField2;
	            if ( m_cStringDelimiter != '\0' )
		            aFirstLine.GetTokenSpecial(aField2,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
	            else
		            aField2 = aField;
                if (aField2.Len() )
                {
                    try
	                {
		                nIndex = m_xNumberFormatter->detectNumberFormat(::com::sun::star::util::NumberFormat::ALL,aField2);
	                }
	                catch(Exception&)
	                {
	                }
                }
            }
        }

	    sal_Int32 nFlags = 0;
	    if (bNumeric)
	    {
		    if (cDecimalDelimiter)
		    {
			    if(io_nPrecisions)
			    {
				    io_nType = DataType::DECIMAL;
                    static const ::rtl::OUString s_sDECIMAL(RTL_CONSTASCII_USTRINGPARAM("DECIMAL"));
				    o_sTypeName = s_sDECIMAL;
			    }
			    else
			    {
				    io_nType = DataType::DOUBLE;
                    static const ::rtl::OUString s_sDOUBLE(RTL_CONSTASCII_USTRINGPARAM("DOUBLE"));
				    o_sTypeName = s_sDOUBLE;
			    }
		    }
		    else
            {
			    io_nType = DataType::INTEGER;
                io_nPrecisions = 0;
                io_nScales = 0;
            }
		    nFlags = ColumnSearch::BASIC;
	    }
	    else
	    {
		    switch (comphelper::getNumberFormatType(m_xNumberFormatter,nIndex))
		    {
			    case NUMBERFORMAT_DATE:
				    io_nType = DataType::DATE;
                    {
                        static const ::rtl::OUString s_sDATE(RTL_CONSTASCII_USTRINGPARAM("DATE"));
				        o_sTypeName = s_sDATE;
                    }
				    break;
			    case NUMBERFORMAT_DATETIME:
				    io_nType = DataType::TIMESTAMP;
                    {
                        static const ::rtl::OUString s_sTIMESTAMP(RTL_CONSTASCII_USTRINGPARAM("TIMESTAMP"));
				        o_sTypeName = s_sTIMESTAMP;
                    }
				    break;
			    case NUMBERFORMAT_TIME:
				    io_nType = DataType::TIME;
                    {
                        static const ::rtl::OUString s_sTIME(RTL_CONSTASCII_USTRINGPARAM("TIME"));
				        o_sTypeName = s_sTIME;
                    }
				    break;
			    default:
				    io_nType = DataType::VARCHAR;
				    io_nPrecisions = 0;	// nyi: Daten koennen aber laenger sein!
				    io_nScales = 0;
                    {
                        static const ::rtl::OUString s_sVARCHAR(RTL_CONSTASCII_USTRINGPARAM("VARCHAR"));
				        o_sTypeName = s_sVARCHAR;
                    }
		    };
		    nFlags |= ColumnSearch::CHAR;
	    }
    }
    else
    {
        String aField;
        aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine,m_cFieldDelimiter,'\0');
        if (aField.Len() == 0 ||
		        (m_cStringDelimiter && m_cStringDelimiter == aField.GetChar(0)))
        {
            if ( m_cStringDelimiter != '\0' )
		        aFirstLine.GetTokenSpecial(aField,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
            else
	            nStartPosFirstLine2 = nStartPosFirstLine;
        }
        else
        {
	        String aField2;
	        if ( m_cStringDelimiter != '\0' )
		        aFirstLine.GetTokenSpecial(aField2,nStartPosFirstLine2,m_cFieldDelimiter,m_cStringDelimiter);
        }
    }
}
// -------------------------------------------------------------------------
OFlatTable::OFlatTable(sdbcx::OCollection* _pTables,OFlatConnection* _pConnection,
					const ::rtl::OUString& _Name,
					const ::rtl::OUString& _Type,
					const ::rtl::OUString& _Description ,
					const ::rtl::OUString& _SchemaName,
					const ::rtl::OUString& _CatalogName
				) : OFlatTable_BASE(_pTables,_pConnection,_Name,
								  _Type,
								  _Description,
								  _SchemaName,
								  _CatalogName)
	,m_nStartRowFilePos(0)
    ,m_nRowPos(0)
	,m_nMaxRowCount(0)
    ,m_cStringDelimiter(_pConnection->getStringDelimiter())
    ,m_cFieldDelimiter(_pConnection->getFieldDelimiter())
    ,m_bNeedToReadLine(false)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::OFlatTable" );

}
// -----------------------------------------------------------------------------
void OFlatTable::construct()
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::construct" );
    SvtSysLocale aLocale;
	::com::sun::star::lang::Locale aAppLocale(aLocale.GetLocaleDataPtr()->getLocale());
	Sequence< ::com::sun::star::uno::Any > aArg(1);
	aArg[0] <<= aAppLocale;

	Reference< ::com::sun::star::util::XNumberFormatsSupplier >  xSupplier(m_pConnection->getDriver()->getFactory()->createInstanceWithArguments(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatsSupplier"),aArg),UNO_QUERY);
	m_xNumberFormatter = Reference< ::com::sun::star::util::XNumberFormatter >(m_pConnection->getDriver()->getFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")),UNO_QUERY);
	m_xNumberFormatter->attachNumberFormatsSupplier(xSupplier);
    Reference<XPropertySet> xProp(xSupplier->getNumberFormatSettings(),UNO_QUERY);
	xProp->getPropertyValue(::rtl::OUString::createFromAscii("NullDate")) >>= m_aNullDate;

	INetURLObject aURL;
	aURL.SetURL(getEntry());

	if(aURL.getExtension() != rtl::OUString(m_pConnection->getExtension()))
		aURL.setExtension(m_pConnection->getExtension());

	String aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE);

	m_pFileStream = createStream_simpleError( aFileName,STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE);

	if(!m_pFileStream)
		m_pFileStream = createStream_simpleError( aFileName,STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYNONE);

	if(m_pFileStream)
	{
		m_pFileStream->Seek(STREAM_SEEK_TO_END);
		sal_Int32 nSize = m_pFileStream->Tell();
		m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);

		// Buffersize abhaengig von der Filegroesse
		m_pFileStream->SetBufferSize(nSize > 1000000 ? 32768 :
									nSize > 100000	? 16384 :
									nSize > 10000	? 4096	: 1024);

		fillColumns(aAppLocale);

		refreshColumns();
	}
}
// -------------------------------------------------------------------------
String OFlatTable::getEntry()
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::getEntry" );
	::rtl::OUString sURL;
	try
	{
		Reference< XResultSet > xDir = m_pConnection->getDir()->getStaticResultSet();
		Reference< XRow> xRow(xDir,UNO_QUERY);
		::rtl::OUString sName;
		::rtl::OUString sExt;

		INetURLObject aURL;
		xDir->beforeFirst();
		static const ::rtl::OUString s_sSeparator(RTL_CONSTASCII_USTRINGPARAM("/"));
		while(xDir->next())
		{
			sName = xRow->getString(1);
			aURL.SetSmartProtocol(INET_PROT_FILE);
			String sUrl = m_pConnection->getURL() +  s_sSeparator + sName;
			aURL.SetSmartURL( sUrl );

			// cut the extension
			sExt = aURL.getExtension();

			// name and extension have to coincide
			if ( m_pConnection->matchesExtension( sExt ) )
			{
				if ( sExt.getLength() )
					sName = sName.replaceAt(sName.getLength()-(sExt.getLength()+1),sExt.getLength()+1,::rtl::OUString());
				if ( sName == m_Name )
				{
					Reference< XContentAccess > xContentAccess( xDir, UNO_QUERY );
					sURL = xContentAccess->queryContentIdentifierString();
					break;
				}
			}
		}
		xDir->beforeFirst(); // move back to before first record
	}
	catch(Exception&)
	{
		OSL_ASSERT(0);
	}
	return sURL.getStr();
}
// -------------------------------------------------------------------------
void OFlatTable::refreshColumns()
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::refreshColumns" );
	::osl::MutexGuard aGuard( m_aMutex );

	TStringVector aVector;
	aVector.reserve(m_aColumns->get().size());

	for(OSQLColumns::Vector::const_iterator aIter = m_aColumns->get().begin();aIter != m_aColumns->get().end();++aIter)
		aVector.push_back(Reference< XNamed>(*aIter,UNO_QUERY)->getName());

	if(m_pColumns)
		m_pColumns->reFill(aVector);
	else
		m_pColumns	= new OFlatColumns(this,m_aMutex,aVector);
}

// -------------------------------------------------------------------------
void SAL_CALL OFlatTable::disposing(void)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::disposing" );
	OFileTable::disposing();
	::osl::MutexGuard aGuard(m_aMutex);
	m_aColumns = NULL;
}
// -------------------------------------------------------------------------
Sequence< Type > SAL_CALL OFlatTable::getTypes(  ) throw(RuntimeException)
{
	Sequence< Type > aTypes = OTable_TYPEDEF::getTypes();
	::std::vector<Type> aOwnTypes;
	aOwnTypes.reserve(aTypes.getLength());
	const Type* pBegin = aTypes.getConstArray();
	const Type* pEnd = pBegin + aTypes.getLength();
	for(;pBegin != pEnd;++pBegin)
	{
		if(!(*pBegin == ::getCppuType((const Reference<XKeysSupplier>*)0)	||
			*pBegin == ::getCppuType((const Reference<XRename>*)0)			||
			*pBegin == ::getCppuType((const Reference<XIndexesSupplier>*)0) ||
			*pBegin == ::getCppuType((const Reference<XAlterTable>*)0)		||
			*pBegin == ::getCppuType((const Reference<XDataDescriptorFactory>*)0)))
		{
			aOwnTypes.push_back(*pBegin);
		}
	}
	Type *pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0];
	return Sequence< Type >(pTypes, aOwnTypes.size());
}

// -------------------------------------------------------------------------
Any SAL_CALL OFlatTable::queryInterface( const Type & rType ) throw(RuntimeException)
{
	if( rType == ::getCppuType((const Reference<XKeysSupplier>*)0)		||
		rType == ::getCppuType((const Reference<XIndexesSupplier>*)0)	||
		rType == ::getCppuType((const Reference<XRename>*)0)			||
		rType == ::getCppuType((const Reference<XAlterTable>*)0)		||
		rType == ::getCppuType((const Reference<XDataDescriptorFactory>*)0))
		return Any();

	Any aRet = OTable_TYPEDEF::queryInterface(rType);
	return aRet.hasValue() ? aRet : ::cppu::queryInterface(rType,static_cast< ::com::sun::star::lang::XUnoTunnel*> (this));
}

//--------------------------------------------------------------------------
Sequence< sal_Int8 > OFlatTable::getUnoTunnelImplementationId()
{
	static ::cppu::OImplementationId * pId = 0;
	if (! pId)
	{
		::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
		if (! pId)
		{
			static ::cppu::OImplementationId aId;
			pId = &aId;
		}
	}
	return pId->getImplementationId();
}

// com::sun::star::lang::XUnoTunnel
//------------------------------------------------------------------
sal_Int64 OFlatTable::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::getSomething" );
	return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
				? reinterpret_cast< sal_Int64 >( this )
				: OFlatTable_BASE::getSomething(rId);
}
//------------------------------------------------------------------
sal_Bool OFlatTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols,sal_Bool bIsTable,sal_Bool bRetrieveData)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::fetchRow" );
	*(_rRow->get())[0] = m_nFilePos;

	if (!bRetrieveData)
		return sal_True;
    if ( m_bNeedToReadLine )
    {        
        sal_Int32 nCurrentPos = 0;
        m_pFileStream->Seek(m_nFilePos);
        readLine(nCurrentPos);
        m_bNeedToReadLine = false;
    }

	OFlatConnection* pConnection = (OFlatConnection*)m_pConnection;
    const sal_Unicode cDecimalDelimiter = pConnection->getDecimalDelimiter();
	const sal_Unicode cThousandDelimiter = pConnection->getThousandDelimiter();
	// Felder:
	xub_StrLen nStartPos = 0;
	String aStr;
    OSQLColumns::Vector::const_iterator aIter = _rCols.get().begin();
    OSQLColumns::Vector::const_iterator aEnd = _rCols.get().end();
    const OValueRefVector::Vector::size_type nCount = _rRow->get().size();
	for (OValueRefVector::Vector::size_type i = 1; aIter != aEnd && i < nCount;
         ++aIter, i++)
	{
        m_aCurrentLine.GetTokenSpecial(aStr,nStartPos,m_cFieldDelimiter,m_cStringDelimiter);

		if (aStr.Len() == 0)
			(_rRow->get())[i]->setNull();
		else
		{
			// Laengen je nach Datentyp:
			sal_Int32	nLen,
						nType = 0;
			if(bIsTable)
			{
				nLen	= m_aPrecisions[i-1];
				nType	= m_aTypes[i-1];
			}
			else
			{
				Reference< XPropertySet> xColumn = *aIter;
				xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION))	>>= nLen;
				xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))		>>= nType;
			}
			switch(nType)
			{
				case DataType::TIMESTAMP:
				case DataType::DATE:
				case DataType::TIME:
				{
					try
					{
						double nRes = m_xNumberFormatter->convertStringToNumber(::com::sun::star::util::NumberFormat::ALL,aStr);

						switch(nType)
						{
							case DataType::DATE:
								*(_rRow->get())[i] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(nRes,m_aNullDate));
								break;
							case DataType::TIMESTAMP:
								*(_rRow->get())[i] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(nRes,m_aNullDate));
								break;
							default:
								*(_rRow->get())[i] = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(nRes));
						}
					}
					catch(Exception&)
					{
						(_rRow->get())[i]->setNull();
					}
				}	break;
				case DataType::DOUBLE:
				case DataType::INTEGER:
				case DataType::DECIMAL:				// #99178# OJ
				case DataType::NUMERIC:
				{
					
					String aStrConverted;
                    if ( DataType::INTEGER != nType )
                    {
                        sal_Unicode* pData = aStrConverted.AllocBuffer(aStr.Len());
                        const sal_Unicode* pStart = pData;

					    OSL_ENSURE(cDecimalDelimiter && nType != DataType::INTEGER ||
							       !cDecimalDelimiter && nType == DataType::INTEGER,
							       "FalscherTyp");

					    // In Standard-Notation (DezimalPUNKT ohne Tausender-Komma) umwandeln:
					    for (xub_StrLen j = 0; j < aStr.Len(); ++j)
					    {
                            const sal_Unicode cChar = aStr.GetChar(j); 
						    if (cDecimalDelimiter && cChar == cDecimalDelimiter)
                                *pData++ = '.';
							    //aStrConverted.Append( '.' );
						    else if ( cChar == '.' ) // special case, if decimal seperator isn't '.' we have to put the string after it
							    continue; // #99189# OJ
						    else if (cThousandDelimiter && cChar == cThousandDelimiter)
						    {
							    // weglassen
						    }
						    else
                                *pData++ = cChar;
							    //aStrConverted.Append(cChar);
					    } // for (xub_StrLen j = 0; j < aStr.Len(); ++j)
                        aStrConverted.ReleaseBufferAccess(xub_StrLen(pData - pStart));
                    } // if ( DataType::INTEGER != nType )
                    else
                    {
                        aStrConverted = aStr;
                        if ( cThousandDelimiter )
                            aStrConverted.EraseAllChars(cThousandDelimiter);
                    }
					const double nVal = ::rtl::math::stringToDouble(aStrConverted,'.',',',NULL,NULL);

					// #99178# OJ
					if ( DataType::DECIMAL == nType || DataType::NUMERIC == nType )
                        *(_rRow->get())[i] = ::rtl::OUString::valueOf(nVal);
					else
						*(_rRow->get())[i] = nVal;
				} break;

				default:
				{
					// Wert als String in Variable der Row uebernehmen
					*(_rRow->get())[i] = ORowSetValue(aStr);
				}
				break;
			} // switch(nType)
            (_rRow->get())[i]->setTypeKind(nType);
		}
	}
	return sal_True;
}
void OFlatTable::refreshHeader()
{
    m_nRowPos = 0;
}
// -----------------------------------------------------------------------------
sal_Bool OFlatTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "Ocke.Janssen@sun.com", "OFlatTable::seekRow" );
	OSL_ENSURE(m_pFileStream,"OFlatTable::seekRow: FileStream is NULL!");
	// ----------------------------------------------------------
	// Positionierung vorbereiten:
	m_nFilePos = nCurPos;

	switch(eCursorPosition)
	{
		case IResultSetHelper::FIRST:
			m_nRowPos = 0;
            // run through
		case IResultSetHelper::NEXT:
            {
			    ++m_nRowPos;            
                ::std::map<sal_Int32,TRowPositionsInFile::iterator>::const_iterator aFind = m_aRowPosToFilePos.find(m_nRowPos);
                m_bNeedToReadLine = aFind != m_aRowPosToFilePos.end();
                if ( m_bNeedToReadLine )
                {
                    m_nFilePos  = aFind->second->first;
                    nCurPos     = aFind->second->second;
                } // if ( m_bNeedToReadLine )
                else
                {
                    if ( m_nRowPos == 1 )
                        m_nFilePos = m_nStartRowFilePos;
			        m_pFileStream->Seek(m_nFilePos);
			        if ( m_pFileStream->IsEof() || !readLine(nCurPos) /*|| !checkHeaderLine()*/)
			        {
				        m_nMaxRowCount = m_nRowPos -1;
				        return sal_False;
			        } // if ( m_pFileStream->IsEof() || !readLine(nCurPos) /*|| !checkHeaderLine()*/) 

                    TRowPositionsInFile::iterator aPos = m_aFilePosToEndLinePos.insert(TRowPositionsInFile::value_type(m_nFilePos,nCurPos)).first;
                    m_aRowPosToFilePos.insert(::std::map<sal_Int32,TRowPositionsInFile::iterator>::value_type(m_nRowPos,aPos));
                }
            }
			
			break;
		case IResultSetHelper::PRIOR:
			--m_nRowPos;
			if(m_nRowPos > 0)
			{
                TRowPositionsInFile::iterator aPositions = m_aRowPosToFilePos[m_nRowPos];
				m_nFilePos = aPositions->first;
                nCurPos = aPositions->second;
                m_bNeedToReadLine = true;
			}
			else
				m_nRowPos = 0;

			break;
		case IResultSetHelper::LAST:
			if ( m_nMaxRowCount )
			{
                ::std::map<sal_Int32,TRowPositionsInFile::iterator>::reverse_iterator aLastPos = m_aRowPosToFilePos.rbegin();
                m_nRowPos  = aLastPos->first;
				m_nFilePos = aLastPos->second->first;
                nCurPos    = aLastPos->second->second;
				
				//m_pFileStream->Seek(m_nFilePos);
                m_bNeedToReadLine = true;
				//if ( m_pFileStream->IsEof() /*|| !checkHeaderLine()*/ || !readLine(nCurPos) )
				//	return sal_False;
			}
			else
			{
				while(seekRow(IResultSetHelper::NEXT,1,nCurPos)) ; // run through after last row
				// now I know all
				seekRow(IResultSetHelper::PRIOR,1,nCurPos);
			}
			break;
		case IResultSetHelper::RELATIVE:
			if(nOffset > 0)
			{
				for(sal_Int32 i = 0;i<nOffset;++i)
					seekRow(IResultSetHelper::NEXT,1,nCurPos);
			}
			else if(nOffset < 0)
			{
				for(sal_Int32 i = nOffset;i;++i)
					seekRow(IResultSetHelper::PRIOR,1,nCurPos);
			}
			break;
		case IResultSetHelper::ABSOLUTE:
			{
				if(nOffset < 0)
					nOffset = m_nRowPos + nOffset;
				::std::map<sal_Int32,TRowPositionsInFile::iterator>::const_iterator aIter = m_aRowPosToFilePos.find(nOffset);
				if(aIter != m_aRowPosToFilePos.end())
				{
					m_nFilePos  = aIter->second->first;
                    nCurPos     = aIter->second->second;
					//m_pFileStream->Seek(m_nFilePos);
                    m_bNeedToReadLine = true;
					//if ( m_pFileStream->IsEof() /*|| !checkHeaderLine()*/ || !readLine(nCurPos) )
					//	return sal_False;
				}
				else if(m_nMaxRowCount && nOffset > m_nMaxRowCount) // offset is outside the table
				{
					m_nRowPos = m_nMaxRowCount;
					return sal_False;
				}
				else
				{
					aIter = m_aRowPosToFilePos.upper_bound(nOffset);
					if(aIter == m_aRowPosToFilePos.end())
					{
                        ::std::map<sal_Int32,TRowPositionsInFile::iterator>::reverse_iterator aLastPos = m_aRowPosToFilePos.rbegin();
						m_nRowPos	= aLastPos->first;
						nCurPos = m_nFilePos = aLastPos->second->first;
						while(m_nRowPos != nOffset)
							seekRow(IResultSetHelper::NEXT,1,nCurPos);
					}
					else
					{
						--aIter;
						m_nRowPos	= aIter->first;
						m_nFilePos	= aIter->second->first;
                        nCurPos	    = aIter->second->second;
						//m_pFileStream->Seek(m_nFilePos);
                        m_bNeedToReadLine = true;
						//if ( m_pFileStream->IsEof() /*|| !checkHeaderLine()*/ || !readLine(nCurPos) )
						//	return sal_False;
					}
				}
			}

			break;
		case IResultSetHelper::BOOKMARK:
            {
                TRowPositionsInFile::const_iterator aFind = m_aFilePosToEndLinePos.find(nOffset);
                m_bNeedToReadLine = aFind != m_aFilePosToEndLinePos.end();
                if ( m_bNeedToReadLine )
                {
                    m_nFilePos  = aFind->first;
                    nCurPos = aFind->second;
                }
                else 
                {
                    m_nFilePos = nOffset;
                    m_pFileStream->Seek(nOffset);
			        if (m_pFileStream->IsEof() || !readLine(nCurPos) )
				        return sal_False;
                }
                break;
            }
	}

    //nCurPos = m_nFilePos;

	return sal_True;
}
// -----------------------------------------------------------------------------
sal_Bool OFlatTable::readLine(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;

    QuotedTokenizedString sLine = m_aCurrentLine; // 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;
        }
        else
            break;
    }
    _rnCurrentPos = m_pFileStream->Tell();
    return sal_True;
}

