[ooo-build-commit] Branch 'ooo-build-3-1-1' - patches/dev300
Kohei Yoshida
kohei at kemper.freedesktop.org
Wed Dec 9 17:24:03 PST 2009
patches/dev300/apply | 7
patches/dev300/calc-perf-import-dbf-connectivity.diff | 99 +
patches/dev300/calc-perf-import-dbf-sc.diff | 968 ++++++++++++++++++
patches/dev300/sal-strintern-speed-char-upper.diff | 215 +++
4 files changed, 1289 insertions(+)
New commits:
commit e0e0eca4f9011d97286448143b4232ea8a81a5c3
Author: Kohei Yoshida <kyoshida at novell.com>
Date: Wed Dec 9 17:50:15 2009 -0500
Ported the DBF import performance patches from master.
They are _disabled_ in the default build.
* patches/dev300/apply:
* patches/dev300/calc-perf-import-dbf-connectivity.diff:
* patches/dev300/calc-perf-import-dbf-sc.diff:
* patches/dev300/sal-strintern-speed-char-upper.diff:
diff --git a/patches/dev300/apply b/patches/dev300/apply
index 9ebc84b..418fd20 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -3492,6 +3492,13 @@ calc-perf-page-and-manual-breaks-fwd-iterator.diff, n#503482, kohei
# Refactor row height storage to speed up page break updates.
calc-perf-speedup-pagebreak-update.diff, n#554955, kohei
+# string interning optimization for various IBM encoding types.
+sal-strintern-speed-char-upper.diff, kohei
+
+# speed optimization for dbf import.
+calc-perf-import-dbf-connectivity.diff, kohei
+calc-perf-import-dbf-sc.diff, kohei
+
[ AutoLayout ]
sd-layoutcode.diff, cocofan
offapi-layoutcode.diff, cocofan
diff --git a/patches/dev300/calc-perf-import-dbf-connectivity.diff b/patches/dev300/calc-perf-import-dbf-connectivity.diff
new file mode 100644
index 0000000..6395f84
--- /dev/null
+++ b/patches/dev300/calc-perf-import-dbf-connectivity.diff
@@ -0,0 +1,99 @@
+diff --git connectivity/source/drivers/dbase/DTable.cxx connectivity/source/drivers/dbase/DTable.cxx
+index 0db2f41..3498e39 100644
+--- connectivity/source/drivers/dbase/DTable.cxx
++++ connectivity/source/drivers/dbase/DTable.cxx
+@@ -686,50 +686,66 @@ sal_Bool ODbaseTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols, s
+
+ if (nType == DataType::CHAR || nType == DataType::VARCHAR)
+ {
+- char cLast = pData[nLen];
+- pData[nLen] = 0;
+- String aStr(pData,(xub_StrLen)nLen,m_eEncoding);
+- aStr.EraseTrailingChars();
+-
+- if ( aStr.Len() )
+- *(_rRow->get())[i] = ::rtl::OUString(aStr);
+- else// keine StringLaenge, dann NULL
++ sal_Int32 nLastPos = -1;
++ for (sal_Int32 k = 0; k < nLen; ++k)
++ {
++ if (pData[k] != ' ')
++ // Record last non-empty position.
++ nLastPos = k;
++ }
++ if (nLastPos < 0)
++ {
++ // Empty string. Skip it.
+ (_rRow->get())[i]->setNull();
+-
+- pData[nLen] = cLast;
++ }
++ else
++ {
++ // Commit the string. Use intern() to ref-count it.
++ *(_rRow->get())[i] = ::rtl::OUString::intern(pData, static_cast<sal_Int32>(nLastPos+1), m_eEncoding);
++ }
+ }
+ else
+ {
++ sal_Int32 nPos1 = -1, nPos2 = -1;
+ // Falls Nul-Zeichen im String enthalten sind, in Blanks umwandeln!
+ for (sal_Int32 k = 0; k < nLen; k++)
+ {
+ if (pData[k] == '\0')
+ pData[k] = ' ';
+- }
+
+- String aStr(pData, (xub_StrLen)nLen,m_eEncoding); // Spaces am Anfang und am Ende entfernen:
+- aStr.EraseLeadingChars();
+- aStr.EraseTrailingChars();
++ if (pData[k] != ' ')
++ {
++ if (nPos1 < 0)
++ // first non-empty char position.
++ nPos1 = k;
+
+- if (!aStr.Len())
++ // last non-empty char position.
++ nPos2 = k;
++ }
++ }
++
++ if (nPos1 < 0)
+ {
++ // Empty string. Skip it.
+ nByteOffset += nLen;
+ (_rRow->get())[i]->setNull(); // keine Werte -> fertig
+ continue;
+ }
+
++ ::rtl::OUString aStr = ::rtl::OUString::intern(pData+nPos1, nPos2-nPos1+1, m_eEncoding);
++
+ switch (nType)
+ {
+ case DataType::DATE:
+ {
+- if (aStr.Len() != nLen)
++ if (aStr.getLength() != nLen)
+ {
+ (_rRow->get())[i]->setNull();
+ break;
+ }
+- const sal_uInt16 nYear = (sal_uInt16)aStr.Copy( 0, 4 ).ToInt32();
+- const sal_uInt16 nMonth = (sal_uInt16)aStr.Copy( 4, 2 ).ToInt32();
+- const sal_uInt16 nDay = (sal_uInt16)aStr.Copy( 6, 2 ).ToInt32();
++ const sal_uInt16 nYear = (sal_uInt16)aStr.copy( 0, 4 ).toInt32();
++ const sal_uInt16 nMonth = (sal_uInt16)aStr.copy( 4, 2 ).toInt32();
++ const sal_uInt16 nDay = (sal_uInt16)aStr.copy( 6, 2 ).toInt32();
+
+ const ::com::sun::star::util::Date aDate(nDay,nMonth,nYear);
+ *(_rRow->get())[i] = aDate;
+@@ -755,7 +772,7 @@ sal_Bool ODbaseTable::fetchRow(OValueRefRow& _rRow,const OSQLColumns & _rCols, s
+ break;
+ case DataType::LONGVARCHAR:
+ {
+- const long nBlockNo = aStr.ToInt32(); // Blocknummer lesen
++ const long nBlockNo = aStr.toInt32(); // Blocknummer lesen
+ if (nBlockNo > 0 && m_pMemoStream) // Daten aus Memo-Datei lesen, nur wenn
+ {
+ if ( !ReadMemo(nBlockNo, (_rRow->get())[i]->get()) )
diff --git a/patches/dev300/calc-perf-import-dbf-sc.diff b/patches/dev300/calc-perf-import-dbf-sc.diff
new file mode 100644
index 0000000..a5959fc
--- /dev/null
+++ b/patches/dev300/calc-perf-import-dbf-sc.diff
@@ -0,0 +1,968 @@
+diff --git sc/inc/column.hxx sc/inc/column.hxx
+index a39a958..48ed045 100644
+--- sc/inc/column.hxx
++++ sc/inc/column.hxx
+@@ -73,6 +73,7 @@ struct ScLineFlags;
+ struct ScMergePatternState;
+ class ScFlatBoolRowSegments;
+ struct ScSetStringParam;
++struct ScColWidthParam;
+
+ #define COLUMN_DELTA 4
+
+@@ -129,8 +130,16 @@ friend class ScHorizontalCellIterator;
+ friend class ScHorizontalAttrIterator;
+
+ public:
+-static BOOL bDoubleAlloc; // fuer Import: Groesse beim Allozieren verdoppeln
++ static bool bDoubleAlloc; // fuer Import: Groesse beim Allozieren verdoppeln
+
++ class DoubleAllocSwitch
++ {
++ public:
++ DoubleAllocSwitch(bool bNewVal = true);
++ ~DoubleAllocSwitch();
++ private:
++ bool mbOldVal;
++ };
+ public:
+ ScColumn();
+ ~ScColumn();
+@@ -370,7 +379,7 @@ public:
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bFormula, USHORT nOldWidth,
+ const ScMarkData* pMarkData,
+- BOOL bSimpleTextImport );
++ const ScColWidthParam* pParam );
+ void GetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT* pHeight,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+diff --git sc/inc/dbdocutl.hxx sc/inc/dbdocutl.hxx
+index 52d2680..d3cddf7 100644
+--- sc/inc/dbdocutl.hxx
++++ sc/inc/dbdocutl.hxx
+@@ -45,10 +45,20 @@ namespace com { namespace sun { namespace star { namespace sdbc {
+ class ScDatabaseDocUtil
+ {
+ public:
++ /**
++ * Detailed information on single string value.
++ */
++ struct StrData
++ {
++ bool mbSimpleText;
++ sal_uInt32 mnStrLength;
++
++ StrData();
++ };
+ static void PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::sdbc::XRow>& xRow, long nRowPos,
+- long nType, BOOL bCurrency, BOOL* pSimpleFlag = NULL );
++ long nType, BOOL bCurrency, StrData* pStrData = NULL );
+ };
+
+ #endif
+diff --git sc/inc/dociter.hxx sc/inc/dociter.hxx
+index d5d4235..bd40623 100644
+--- sc/inc/dociter.hxx
++++ sc/inc/dociter.hxx
+@@ -36,12 +36,16 @@
+ #include "global.hxx"
+ #include "scdllapi.h"
+
++#include <vector>
++#include <boost/shared_ptr.hpp>
++
+ class ScDocument;
+ class ScBaseCell;
+ class ScPatternAttr;
+ class ScAttrArray;
+ class ScAttrIterator;
+ class ScRange;
++class ScFlatBoolRowSegments;
+
+ class ScDocumentIterator // alle nichtleeren Zellen durchgehen
+ {
+@@ -451,6 +455,42 @@ public:
+ const ScBaseCell* GetCell() const { return pFoundCell; }
+ };
+
++// ============================================================================
++
++class ScDocRowHeightUpdater
++{
++public:
++ struct TabRanges
++ {
++ SCTAB mnTab;
++ ::boost::shared_ptr<ScFlatBoolRowSegments> mpRanges;
++
++ TabRanges();
++ TabRanges(SCTAB nTab);
++ };
++
++ /**
++ * Passing a NULL pointer to pTabRangesArray forces the heights of all
++ * rows in all tables to be updated.
++ */
++ explicit ScDocRowHeightUpdater(
++ ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY,
++ const ::std::vector<TabRanges>* pTabRangesArray = NULL);
++
++ void update();
++
++private:
++ void updateAll();
++
++private:
++ ScDocument& mrDoc;
++ OutputDevice* mpOutDev;
++ double mfPPTX;
++ double mfPPTY;
++ const ::std::vector<TabRanges>* mpTabRangesArray;
++};
++
++
+ #endif
+
+
+diff --git sc/inc/docparam.hxx sc/inc/docparam.hxx
+new file mode 100644
+index 0000000..e273c01
+--- /dev/null
++++ sc/inc/docparam.hxx
+@@ -0,0 +1,47 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: document.hxx,v $
++ * $Revision: 1.115.36.9 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org. If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef SC_DOCPARAM_HXX
++#define SC_DOCPARAM_HXX
++
++#include "address.hxx"
++
++// Let's put here misc structures that get passed to ScDocument's methods.
++
++struct ScColWidthParam
++{
++ SCROW mnMaxTextRow;
++ sal_uInt32 mnMaxTextLen;
++ bool mbSimpleText;
++
++ ScColWidthParam();
++};
++
++#endif
+diff --git sc/inc/document.hxx sc/inc/document.hxx
+index 26d19a9..1ab39fd 100644
+--- sc/inc/document.hxx
++++ sc/inc/document.hxx
+@@ -143,6 +143,8 @@ struct ScLookupCacheMapImpl;
+ struct ScClipParam;
+ struct ScClipRangeNameData;
+ struct ScSetStringParam;
++class ScDocRowHeightUpdater;
++struct ScColWidthParam;
+
+ namespace com { namespace sun { namespace star {
+ namespace lang {
+@@ -245,6 +247,7 @@ friend class ScHorizontalCellIterator;
+ friend class ScHorizontalAttrIterator;
+ friend class ScDocAttrIterator;
+ friend class ScAttrRectIterator;
++friend class ScDocRowHeightUpdater;
+ #if OLD_PIVOT_IMPLEMENTATION
+ friend class ScPivot;
+ #endif
+@@ -1264,7 +1267,7 @@ public:
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bFormula,
+ const ScMarkData* pMarkData = NULL,
+- BOOL bSimpleTextImport = FALSE );
++ const ScColWidthParam* pParam = NULL );
+ SC_DLLPUBLIC BOOL SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, USHORT nExtra,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+diff --git sc/inc/segmenttree.hxx sc/inc/segmenttree.hxx
+index 9b9d753..3199f7d 100644
+--- sc/inc/segmenttree.hxx
++++ sc/inc/segmenttree.hxx
+@@ -63,6 +63,16 @@ public:
+ bool mbCurValue;
+ };
+
++ class RangeIterator
++ {
++ public:
++ explicit RangeIterator(ScFlatBoolRowSegments& rSegs);
++ bool getFirst(RangeData& rRange);
++ bool getNext(RangeData& rRange);
++ private:
++ ScFlatBoolRowSegments& mrSegs;
++ };
++
+ ScFlatBoolRowSegments();
+ ~ScFlatBoolRowSegments();
+
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index db301be..a71ac29 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -87,6 +87,7 @@ class ScFlatUInt16RowSegments;
+ class ScFlatBoolRowSegments;
+ class ScFlatBoolColSegments;
+ struct ScSetStringParam;
++struct ScColWidthParam;
+
+ class ScTable
+ {
+@@ -573,7 +574,7 @@ public:
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bFormula, const ScMarkData* pMarkData,
+- BOOL bSimpleTextImport );
++ const ScColWidthParam* pParam );
+ BOOL SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT nExtra,
+ OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+diff --git sc/source/core/data/column.cxx sc/source/core/data/column.cxx
+index 76ecf13..0702976 100644
+--- sc/source/core/data/column.cxx
++++ sc/source/core/data/column.cxx
+@@ -70,8 +70,20 @@ inline BOOL IsAmbiguousScriptNonZero( BYTE nScript )
+ nScript != 0 );
+ }
+
+-// -----------------------------------------------------------------------------------------
++// ----------------------------------------------------------------------------
+
++ScColumn::DoubleAllocSwitch::DoubleAllocSwitch(bool bNewVal) :
++ mbOldVal(ScColumn::bDoubleAlloc)
++{
++ ScColumn::bDoubleAlloc = bNewVal;
++}
++
++ScColumn::DoubleAllocSwitch::~DoubleAllocSwitch()
++{
++ ScColumn::bDoubleAlloc = mbOldVal;
++}
++
++// ----------------------------------------------------------------------------
+
+ ScColumn::ScColumn() :
+ nCol( 0 ),
+diff --git sc/source/core/data/column2.cxx sc/source/core/data/column2.cxx
+index 6295c28..cd04467 100644
+--- sc/source/core/data/column2.cxx
++++ sc/source/core/data/column2.cxx
+@@ -70,6 +70,7 @@
+ #include "dbcolect.hxx"
+ #include "fillinfo.hxx"
+ #include "segmenttree.hxx"
++#include "docparam.hxx"
+
+ #include <math.h>
+
+@@ -637,10 +638,10 @@ long ScColumn::GetSimpleTextNeededSize( SCSIZE nIndex, OutputDevice* pDev,
+ }
+
+ USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nPPTY,
+- const Fraction& rZoomX, const Fraction& rZoomY,
+- BOOL bFormula, USHORT nOldWidth,
+- const ScMarkData* pMarkData,
+- BOOL bSimpleTextImport )
++ const Fraction& rZoomX, const Fraction& rZoomY,
++ BOOL bFormula, USHORT nOldWidth,
++ const ScMarkData* pMarkData,
++ const ScColWidthParam* pParam )
+ {
+ if (nCount == 0)
+ return nOldWidth;
+@@ -650,7 +651,7 @@ USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nP
+
+ SCSIZE nIndex;
+ ScMarkedDataIter aDataIter(this, pMarkData, TRUE);
+- if ( bSimpleTextImport )
++ if ( pParam && pParam->mbSimpleText )
+ { // alles eins bis auf NumberFormate
+ const ScPatternAttr* pPattern = GetPattern( 0 );
+ Font aFont;
+@@ -661,19 +662,44 @@ USHORT ScColumn::GetOptimalColWidth( OutputDevice* pDev, double nPPTX, double nP
+ long nMargin = (long) ( pMargin->GetLeftMargin() * nPPTX ) +
+ (long) ( pMargin->GetRightMargin() * nPPTX );
+
+- while (aDataIter.Next( nIndex ))
++ // Try to find the row that has the longest string, and measure the width of that string.
++ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
++ ULONG nFormat = pPattern->GetNumberFormat( pFormatter );
++ String aLongStr;
++ Color* pColor;
++ if (pParam->mnMaxTextRow >= 0)
+ {
+- USHORT nThis = (USHORT) (GetSimpleTextNeededSize( nIndex, pDev,
+- TRUE ) + nMargin);
+- if (nThis)
++ ScBaseCell* pCell = GetCell(pParam->mnMaxTextRow);
++ ScCellFormat::GetString(
++ pCell, nFormat, aLongStr, &pColor, *pFormatter, TRUE, FALSE, ftCheck );
++ }
++ else
++ {
++ xub_StrLen nLongLen = 0;
++ while (aDataIter.Next(nIndex))
+ {
+- if (nThis>nWidth || !bFound)
++ if (nIndex >= nCount)
++ // Out-of-bound reached. No need to keep going.
++ break;
++
++ ScBaseCell* pCell = pItems[nIndex].pCell;
++ String aValStr;
++ ScCellFormat::GetString(
++ pCell, nFormat, aValStr, &pColor, *pFormatter, TRUE, FALSE, ftCheck );
++
++ if (aValStr.Len() > nLongLen)
+ {
+- nWidth = nThis;
+- bFound = TRUE;
++ nLongLen = aValStr.Len();
++ aLongStr = aValStr;
+ }
+ }
+ }
++
++ if (aLongStr.Len())
++ {
++ nWidth = pDev->GetTextWidth(aLongStr) + static_cast<USHORT>(nMargin);
++ bFound = true;
++ }
+ }
+ else
+ {
+diff --git sc/source/core/data/column3.cxx sc/source/core/data/column3.cxx
+index a37a53e..c4e3748 100644
+--- sc/source/core/data/column3.cxx
++++ sc/source/core/data/column3.cxx
+@@ -68,7 +68,7 @@ extern const ScFormulaCell* pLastFormulaTreeTop; // in cellform.cxx
+ using namespace formula;
+ // STATIC DATA -----------------------------------------------------------
+
+-BOOL ScColumn::bDoubleAlloc = FALSE; // fuer Import: Groesse beim Allozieren verdoppeln
++bool ScColumn::bDoubleAlloc = FALSE; // fuer Import: Groesse beim Allozieren verdoppeln
+
+
+ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
+diff --git sc/source/core/data/dbdocutl.cxx sc/source/core/data/dbdocutl.cxx
+index 707f0da..a1146ad 100644
+--- sc/source/core/data/dbdocutl.cxx
++++ sc/source/core/data/dbdocutl.cxx
+@@ -49,12 +49,19 @@ using namespace ::com::sun::star;
+
+ #define D_TIMEFACTOR 86400.0
+
+-// -----------------------------------------------------------------------
++// ----------------------------------------------------------------------------
++
++ScDatabaseDocUtil::StrData::StrData() :
++ mbSimpleText(true), mnStrLength(0)
++{
++}
++
++// ----------------------------------------------------------------------------
+
+ // static
+ void ScDatabaseDocUtil::PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
+ const uno::Reference<sdbc::XRow>& xRow, long nRowPos,
+- long nType, BOOL bCurrency, BOOL* pSimpleFlag )
++ long nType, BOOL bCurrency, StrData* pStrData )
+ {
+ String aString;
+ double nVal = 0.0;
+@@ -188,8 +195,11 @@ void ScDatabaseDocUtil::PutData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB
+ if (aString.Len())
+ {
+ pCell = ScBaseCell::CreateTextCell( aString, pDoc );
+- if ( pSimpleFlag && pCell->GetCellType() == CELLTYPE_EDIT )
+- *pSimpleFlag = FALSE;
++ if (pStrData)
++ {
++ pStrData->mbSimpleText = pCell->GetCellType() != CELLTYPE_EDIT;
++ pStrData->mnStrLength = aString.Len();
++ }
+ }
+ else
+ pCell = NULL;
+diff --git sc/source/core/data/dociter.cxx sc/source/core/data/dociter.cxx
+index 055c64f..b8dc325 100644
+--- sc/source/core/data/dociter.cxx
++++ sc/source/core/data/dociter.cxx
+@@ -46,6 +46,12 @@
+ #include "patattr.hxx"
+ #include "docoptio.hxx"
+ #include "cellform.hxx"
++#include "segmenttree.hxx"
++#include "progress.hxx"
++#include "globstr.hrc"
++#include "tools/fract.hxx"
++
++using ::std::vector;
+
+
+ // STATIC DATA -----------------------------------------------------------
+@@ -1801,3 +1805,96 @@ const ScPatternAttr* ScAttrRectIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2,
+ return NULL; // is nix mehr
+ }
+
++// ============================================================================
++
++ScDocRowHeightUpdater::TabRanges::TabRanges() :
++ mnTab(0), mpRanges(new ScFlatBoolRowSegments)
++{
++}
++
++ScDocRowHeightUpdater::TabRanges::TabRanges(SCTAB nTab) :
++ mnTab(nTab), mpRanges(new ScFlatBoolRowSegments)
++{
++}
++
++ScDocRowHeightUpdater::ScDocRowHeightUpdater(ScDocument& rDoc, OutputDevice* pOutDev, double fPPTX, double fPPTY, const vector<TabRanges>* pTabRangesArray) :
++ mrDoc(rDoc), mpOutDev(pOutDev), mfPPTX(fPPTX), mfPPTY(fPPTY), mpTabRangesArray(pTabRangesArray)
++{
++}
++
++void ScDocRowHeightUpdater::update()
++{
++ if (!mpTabRangesArray || mpTabRangesArray->empty())
++ {
++ // No ranges defined. Update all rows in all tables.
++ updateAll();
++ return;
++ }
++
++ sal_uInt32 nCellCount = 0;
++ vector<TabRanges>::const_iterator itr = mpTabRangesArray->begin(), itrEnd = mpTabRangesArray->end();
++ for (; itr != itrEnd; ++itr)
++ {
++ ScFlatBoolRowSegments::RangeData aData;
++ ScFlatBoolRowSegments::RangeIterator aRangeItr(*itr->mpRanges);
++ for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
++ {
++ if (!aData.mbValue)
++ continue;
++
++ nCellCount += aData.mnRow2 - aData.mnRow1 + 1;
++ }
++ }
++
++ ScProgress aProgress(mrDoc.GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount);
++
++ Fraction aZoom(1, 1);
++ itr = mpTabRangesArray->begin();
++ sal_uInt32 nProgressStart = 0;
++ for (; itr != itrEnd; ++itr)
++ {
++ SCTAB nTab = itr->mnTab;
++ if (!ValidTab(nTab) || !mrDoc.pTab[nTab])
++ continue;
++
++ ScFlatBoolRowSegments::RangeData aData;
++ ScFlatBoolRowSegments::RangeIterator aRangeItr(*itr->mpRanges);
++ for (bool bFound = aRangeItr.getFirst(aData); bFound; bFound = aRangeItr.getNext(aData))
++ {
++ if (!aData.mbValue)
++ continue;
++
++ mrDoc.pTab[nTab]->SetOptimalHeight(
++ aData.mnRow1, aData.mnRow2, 0, mpOutDev, mfPPTX, mfPPTY, aZoom, aZoom, false, &aProgress, nProgressStart);
++
++ nProgressStart += aData.mnRow2 - aData.mnRow1 + 1;
++ }
++ }
++}
++
++void ScDocRowHeightUpdater::updateAll()
++{
++ sal_uInt32 nCellCount = 0;
++ for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab)
++ {
++ if (!ValidTab(nTab) || !mrDoc.pTab[nTab])
++ continue;
++
++ nCellCount += mrDoc.pTab[nTab]->GetWeightedCount();
++ }
++
++ ScProgress aProgress(mrDoc.GetDocumentShell(), ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nCellCount);
++
++ Fraction aZoom(1, 1);
++ ULONG nProgressStart = 0;
++ for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab)
++ {
++ if (!ValidTab(nTab) || !mrDoc.pTab[nTab])
++ continue;
++
++ mrDoc.pTab[nTab]->SetOptimalHeight(
++ 0, MAXROW, 0, mpOutDev, mfPPTX, mfPPTY, aZoom, aZoom, false, &aProgress, nProgressStart);
++
++ nProgressStart += mrDoc.pTab[nTab]->GetWeightedCount();
++ }
++}
+diff --git sc/source/core/data/docparam.cxx sc/source/core/data/docparam.cxx
+new file mode 100644
+index 0000000..0644dd6
+--- /dev/null
++++ sc/source/core/data/docparam.cxx
+@@ -0,0 +1,40 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: document.hxx,v $
++ * $Revision: 1.115.36.9 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org. If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++// MARKER(update_precomp.py): autogen include statement, do not remove
++#include "precompiled_sc.hxx"
++
++// INCLUDE ---------------------------------------------------------------
++
++#include "docparam.hxx"
++
++ScColWidthParam::ScColWidthParam() :
++ mnMaxTextRow(-1), mnMaxTextLen(0), mbSimpleText(true) {}
++
+diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
+index 579c99a..4285017 100644
+--- sc/source/core/data/document.cxx
++++ sc/source/core/data/document.cxx
+@@ -3078,14 +3078,14 @@ ULONG ScDocument::GetRowOffset( SCROW nRow, SCTAB nTab ) const
+
+
+ USHORT ScDocument::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, OutputDevice* pDev,
+- double nPPTX, double nPPTY,
+- const Fraction& rZoomX, const Fraction& rZoomY,
+- BOOL bFormula, const ScMarkData* pMarkData,
+- BOOL bSimpleTextImport )
++ double nPPTX, double nPPTY,
++ const Fraction& rZoomX, const Fraction& rZoomY,
++ BOOL bFormula, const ScMarkData* pMarkData,
++ const ScColWidthParam* pParam )
+ {
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->GetOptimalColWidth( nCol, pDev, nPPTX, nPPTY,
+- rZoomX, rZoomY, bFormula, pMarkData, bSimpleTextImport );
++ rZoomX, rZoomY, bFormula, pMarkData, pParam );
+ DBG_ERROR("Falsche Tabellennummer");
+ return 0;
+ }
+diff --git sc/source/core/data/makefile.mk sc/source/core/data/makefile.mk
+index 4ac58a9..01ad5fa 100644
+--- sc/source/core/data/makefile.mk
++++ sc/source/core/data/makefile.mk
+@@ -74,6 +74,7 @@ SLOFILES = \
+ $(SLO)$/documen8.obj \
+ $(SLO)$/documen9.obj \
+ $(SLO)$/document.obj \
++ $(SLO)$/docparam.obj \
+ $(SLO)$/dpcachetable.obj \
+ $(SLO)$/dpdimsave.obj \
+ $(SLO)$/dpgroup.obj \
+diff --git sc/source/core/data/segmenttree.cxx sc/source/core/data/segmenttree.cxx
+index 98c5032..b86aca8 100644
+--- sc/source/core/data/segmenttree.cxx
++++ sc/source/core/data/segmenttree.cxx
+@@ -66,9 +66,14 @@ public:
+
+ SCROW findLastNotOf(ValueType nValue) const;
+
++ // range iteration
++ bool getFirst(RangeData& rData);
++ bool getNext(RangeData& rData);
++
+ private:
+ typedef ::mdds::flat_segment_tree<SCCOLROW, ValueType> fst_type;
+ fst_type maSegments;
++ typename fst_type::const_iterator maItr;
+ };
+
+ template<typename _ValueType, typename _ExtValueType>
+@@ -175,6 +180,31 @@ SCCOLROW ScFlatSegmentsImpl<_ValueType, _ExtValueType>::findLastNotOf(ValueType
+ return nPos;
+ }
+
++template<typename _ValueType, typename _ExtValueType>
++bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getFirst(RangeData& rData)
++{
++ maItr = maSegments.begin();
++ return getNext(rData);
++}
++
++template<typename _ValueType, typename _ExtValueType>
++bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getNext(RangeData& rData)
++{
++ typename fst_type::const_iterator itrEnd = maSegments.end();
++ if (maItr == itrEnd)
++ return false;
++
++ rData.mnPos1 = maItr->first;
++ rData.mnValue = maItr->second;
++
++ ++maItr;
++ if (maItr == itrEnd)
++ return false;
++
++ rData.mnPos2 = maItr->first - 1;
++ return true;
++}
++
+ // ============================================================================
+
+ class ScFlatUInt16SegmentsImpl : public ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>
+@@ -245,6 +275,37 @@ SCROW ScFlatBoolRowSegments::ForwardIterator::getLastPos() const
+
+ // ----------------------------------------------------------------------------
+
++ScFlatBoolRowSegments::RangeIterator::RangeIterator(ScFlatBoolRowSegments& rSegs) :
++ mrSegs(rSegs)
++{
++}
++
++bool ScFlatBoolRowSegments::RangeIterator::getFirst(RangeData& rRange)
++{
++ ScFlatBoolSegmentsImpl::RangeData aData;
++ if (!mrSegs.mpImpl->getFirst(aData))
++ return false;
++
++ rRange.mnRow1 = static_cast<SCROW>(aData.mnPos1);
++ rRange.mnRow2 = static_cast<SCROW>(aData.mnPos2);
++ rRange.mbValue = static_cast<bool>(aData.mnValue);
++ return true;
++}
++
++bool ScFlatBoolRowSegments::RangeIterator::getNext(RangeData& rRange)
++{
++ ScFlatBoolSegmentsImpl::RangeData aData;
++ if (!mrSegs.mpImpl->getNext(aData))
++ return false;
++
++ rRange.mnRow1 = static_cast<SCROW>(aData.mnPos1);
++ rRange.mnRow2 = static_cast<SCROW>(aData.mnPos2);
++ rRange.mbValue = static_cast<bool>(aData.mnValue);
++ return true;
++}
++
++// ----------------------------------------------------------------------------
++
+ ScFlatBoolRowSegments::ScFlatBoolRowSegments() :
+ mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXROW)))
+ {
+diff --git sc/source/core/data/table1.cxx sc/source/core/data/table1.cxx
+index 5319b1a..3294c06 100644
+--- sc/source/core/data/table1.cxx
++++ sc/source/core/data/table1.cxx
+@@ -287,10 +287,10 @@ USHORT ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
+ double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ BOOL bFormula, const ScMarkData* pMarkData,
+- BOOL bSimpleTextImport )
++ const ScColWidthParam* pParam )
+ {
+ return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
+- bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, bSimpleTextImport );
++ bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, pParam );
+ }
+
+ long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
+diff --git sc/source/ui/docshell/dbdocimp.cxx sc/source/ui/docshell/dbdocimp.cxx
+index cf25c03..895816d 100644
+--- sc/source/ui/docshell/dbdocimp.cxx
++++ sc/source/ui/docshell/dbdocimp.cxx
+@@ -271,7 +271,7 @@ BOOL ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
+ // ImportDoc - also used for Redo
+ ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO );
+ pImportDoc->InitUndo( pDoc, nTab, nTab );
+- ScColumn::bDoubleAlloc = TRUE;
++ ScColumn::DoubleAllocSwitch aAllocSwitch(true);
+
+ //
+ // get data from database into import document
+@@ -463,7 +463,6 @@ BOOL ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam,
+ DBG_ERROR("Unexpected exception in database");
+ }
+
+- ScColumn::bDoubleAlloc = FALSE;
+ pImportDoc->DoColResize( nTab, rParam.nCol1,nEndCol, 0 );
+
+ //
+diff --git sc/source/ui/docshell/docsh.cxx sc/source/ui/docshell/docsh.cxx
+index a3d74c8..9a007ce 100644
+--- sc/source/ui/docshell/docsh.cxx
++++ sc/source/ui/docshell/docsh.cxx
+@@ -121,9 +121,11 @@
+ #include "warnpassword.hxx"
+ #include "optsolver.hxx"
+ #include "tabprotection.hxx"
++#include "docparam.hxx"
+
+ #include "docsh.hxx"
+ #include "docshimp.hxx"
++#include "sizedev.hxx"
+ #include <rtl/logfile.hxx>
+
+ #include <comphelper/processfactory.hxx>
+@@ -133,12 +135,18 @@
+ #include <com/sun/star/document/VbaEventId.hpp>
+ #include <basic/sbstar.hxx>
+ #include <basic/basmgr.hxx>
++
++#include <vector>
++#include <boost/shared_ptr.hpp>
++
+ using namespace com::sun::star;
+ using namespace com::sun::star::document::VbaEventId;
+
+ using namespace com::sun::star;
+ using ::rtl::OUString;
+ using ::rtl::OUStringBuffer;
++using ::boost::shared_ptr;
++using ::std::vector;
+
+ // STATIC DATA -----------------------------------------------------------
+
+@@ -948,12 +956,13 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+ // ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen
+ BOOL bSetColWidths = FALSE;
+ BOOL bSetSimpleTextColWidths = FALSE;
+- BOOL bSimpleColWidth[MAXCOLCOUNT];
+- memset( bSimpleColWidth, 1, (MAXCOLCOUNT) * sizeof(BOOL) );
++ ScColWidthParam aColWidthParam[MAXCOLCOUNT];
+ ScRange aColWidthRange;
+ // ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen
+ BOOL bSetRowHeights = FALSE;
+
++ vector<ScDocRowHeightUpdater::TabRanges> aRecalcRowRangesArray;
++
+ aConvFilterName.Erase(); //@ #BugId 54198
+
+ // Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron),
+@@ -1152,8 +1161,10 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+ sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
+ }
+
++ ScDocRowHeightUpdater::TabRanges aRecalcRanges(0);
+ ULONG eError = DBaseImport( rMedium.GetPhysicalName(),
+- ScGlobal::GetCharsetValue(sItStr), bSimpleColWidth );
++ ScGlobal::GetCharsetValue(sItStr), aColWidthParam, *aRecalcRanges.mpRanges );
++ aRecalcRowRangesArray.push_back(aRecalcRanges);
+
+ if (eError != eERR_OK)
+ {
+@@ -1167,12 +1178,6 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+ aColWidthRange.aStart.SetRow( 1 ); // Spaltenheader nicht
+ bSetColWidths = TRUE;
+ bSetSimpleTextColWidths = TRUE;
+- // Memo-Felder fuehren zu einem bSimpleColWidth[nCol]==FALSE
+- for ( SCCOL nCol=0; nCol <= MAXCOL && !bSetRowHeights; nCol++ )
+- {
+- if ( !bSimpleColWidth[nCol] )
+- bSetRowHeights = TRUE;
+- }
+ }
+ else if (aFltName.EqualsAscii(pFilterDif))
+ {
+@@ -1386,9 +1391,12 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+ {
+ for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ )
+ {
++ if (!bSetSimpleTextColWidths)
++ aColWidthParam[nCol].mbSimpleText = false;
++
+ USHORT nWidth = aDocument.GetOptimalColWidth(
+ nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoom, aZoom, FALSE, &aMark,
+- (bSetSimpleTextColWidths && bSimpleColWidth[nCol]) );
++ &aColWidthParam[nCol] );
+ aDocument.SetColWidth( nCol, nTab,
+ nWidth + (USHORT)ScGlobal::nLastColWidthExtra );
+ }
+@@ -1400,11 +1408,25 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
+ // nPPTX, nPPTY, aZoom, aZoom, FALSE );
+ // }
+ }
+- if ( bSetRowHeights )
+- UpdateAllRowHeights(); // with vdev or printer, depending on configuration
++
++ if (bSetRowHeights)
++ {
++ // Update all rows in all tables.
++ ScSizeDeviceProvider aProv(this);
++ ScDocRowHeightUpdater aUpdater(aDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), NULL);
++ aUpdater.update();
++ }
++ else if (!aRecalcRowRangesArray.empty())
++ {
++ // Update only specified row ranges for better performance.
++ ScSizeDeviceProvider aProv(this);
++ ScDocRowHeightUpdater aUpdater(aDocument, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), &aRecalcRowRangesArray);
++ aUpdater.update();
++ }
+ }
+ FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
+
++
+ // #73762# invalidate eventually temporary table areas
+ if ( bRet )
+ aDocument.InvalidateTableArea();
+diff --git sc/source/ui/docshell/docsh8.cxx sc/source/ui/docshell/docsh8.cxx
+index c01cda9..fbc8976 100644
+--- sc/source/ui/docshell/docsh8.cxx
++++ sc/source/ui/docshell/docsh8.cxx
+@@ -85,6 +85,8 @@
+ #include "patattr.hxx"
+ #include "scitems.hxx"
+ #include "docpool.hxx"
++#include "segmenttree.hxx"
++#include "docparam.hxx"
+
+ #include <vector>
+
+@@ -248,9 +250,11 @@ static void lcl_setScalesToColumns(ScDocument& rDoc, const vector<long>& rScales
+ }
+ }
+
+-ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
+- BOOL bSimpleColWidth[MAXCOLCOUNT] )
++ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
++ ScColWidthParam aColWidthParam[MAXCOLCOUNT], ScFlatBoolRowSegments& rRowHeightsRecalc )
+ {
++ ScColumn::DoubleAllocSwitch aAllocSwitch(true);
++
+ ULONG nErr = eERR_OK;
+ long i;
+
+@@ -407,16 +411,33 @@ ULONG ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet,
+ BOOL bEnd = FALSE;
+ while ( !bEnd && xRowSet->next() )
+ {
++ bool bSimpleRow = true;
+ if ( nRow <= MAXROW )
+ {
+ SCCOL nCol = 0;
+ for (i=0; i<nColCount; i++)
+ {
++ ScDatabaseDocUtil::StrData aStrData;
+ ScDatabaseDocUtil::PutData( &aDocument, nCol, nRow, 0,
+ xRow, i+1, pTypeArr[i], FALSE,
+- &bSimpleColWidth[nCol] );
++ &aStrData );
++
++ if (aStrData.mnStrLength > aColWidthParam[nCol].mnMaxTextLen)
++ {
++ aColWidthParam[nCol].mnMaxTextLen = aStrData.mnStrLength;
++ aColWidthParam[nCol].mnMaxTextRow = nRow;
++ }
++
++ if (!aStrData.mbSimpleText)
++ {
++ bSimpleRow = false;
++ aColWidthParam[nCol].mbSimpleText = false;
++ }
++
+ ++nCol;
+ }
++ if (!bSimpleRow)
++ rRowHeightsRecalc.setTrue(nRow, nRow);
+ ++nRow;
+ }
+ else // past the end of the spreadsheet
+diff --git sc/source/ui/docshell/impex.cxx sc/source/ui/docshell/impex.cxx
+index 573443d..b036ab4 100644
+--- sc/source/ui/docshell/impex.cxx
++++ sc/source/ui/docshell/impex.cxx
+@@ -1081,8 +1081,7 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm )
+ if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
+ rStrm.StartReadingUnicodeText();
+
+- BOOL bOld = ScColumn::bDoubleAlloc;
+- ScColumn::bDoubleAlloc = TRUE;
++ ScColumn::DoubleAllocSwitch aAllocSwitch(true);
+
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCCOL nEndCol = aRange.aEnd.Col();
+@@ -1283,7 +1282,6 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm )
+ bDetermineRange = !bDetermineRange; // toggle
+ } while (!bDetermineRange);
+
+- ScColumn::bDoubleAlloc = bOld;
+ pDoc->DoColResize( nTab, nStartCol, nEndCol, 0 );
+
+ delete pEnglishTransliteration;
+diff --git sc/source/ui/inc/docsh.hxx sc/source/ui/inc/docsh.hxx
+index 50f1920..24658d7 100644
+--- sc/source/ui/inc/docsh.hxx
++++ sc/source/ui/inc/docsh.hxx
+@@ -76,6 +76,8 @@ class VirtualDevice;
+ class ScImportOptions;
+ class ScDocShellModificator;
+ class ScOptSolverSave;
++class ScFlatBoolRowSegments;
++struct ScColWidthParam;
+
+ namespace sfx2 { class FileDialogHelper; }
+ struct DocShell_Impl;
+@@ -156,7 +158,7 @@ class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener
+ SC_DLLPRIVATE SCTAB GetSaveTab();
+
+ SC_DLLPRIVATE ULONG DBaseImport( const String& rFullFileName, CharSet eCharSet,
+- BOOL bSimpleColWidth[MAXCOLCOUNT] );
++ ScColWidthParam aColWidthParam[MAXCOLCOUNT], ScFlatBoolRowSegments& rRowHeightsRecalc );
+ SC_DLLPRIVATE ULONG DBaseExport( const String& rFullFileName, CharSet eCharSet,
+ BOOL& bHasMemo );
+
diff --git a/patches/dev300/sal-strintern-speed-char-upper.diff b/patches/dev300/sal-strintern-speed-char-upper.diff
new file mode 100644
index 0000000..5f2fdb3
--- /dev/null
+++ b/patches/dev300/sal-strintern-speed-char-upper.diff
@@ -0,0 +1,215 @@
+diff --git sal/rtl/source/ustring.c sal/rtl/source/ustring.c
+index b545ff4..c0cf7b5 100644
+--- sal/rtl/source/ustring.c
++++ sal/rtl/source/ustring.c
+@@ -818,23 +818,53 @@ void SAL_CALL rtl_uString_internConvert( rtl_uString ** newStr,
+ { // try various optimisations
+ if ( len < 0 )
+ len = strlen( str );
+- if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
++ switch ( eTextEncoding )
+ {
+- int i;
+- rtl_uString *pScratch;
+- pScratch = alloca( sizeof( rtl_uString )
+- + len * sizeof (IMPL_RTL_STRCODE ) );
+- for (i = 0; i < len; i++)
++ case RTL_TEXTENCODING_ASCII_US:
+ {
+- /* Check ASCII range */
+- OSL_ENSURE( ((unsigned char)str[i]) <= 127,
+- "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
+- pScratch->buffer[i] = str[i];
++ int i;
++ rtl_uString *pScratch;
++ pScratch = alloca( sizeof( rtl_uString )
++ + len * sizeof (IMPL_RTL_STRCODE ) );
++ for (i = 0; i < len; i++)
++ {
++ /* Check ASCII range */
++ OSL_ENSURE( ((unsigned char)str[i]) <= 127,
++ "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
++ pScratch->buffer[i] = str[i];
++ }
++ pScratch->length = len;
++ rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
++ return;
++ }
++ case RTL_TEXTENCODING_IBM_437:
++ case RTL_TEXTENCODING_IBM_850:
++ case RTL_TEXTENCODING_IBM_860:
++ case RTL_TEXTENCODING_IBM_861:
++ case RTL_TEXTENCODING_IBM_863:
++ case RTL_TEXTENCODING_IBM_865:
++ {
++ rtl_uString *pScratch;
++ rtl_TextToUnicodeConverter hConverter;
++ sal_Size nDestChars, nSrcBytes;
++ sal_uInt32 nInfo;
++
++ hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
++ pScratch = alloca( sizeof(rtl_uString) + len * sizeof (IMPL_RTL_STRCODE) );
++
++ nDestChars = rtl_convertTextToUnicode(
++ hConverter, 0, str, len, pScratch->buffer, len, convertFlags, &nInfo, &nSrcBytes );
++ pScratch->length = len;
++
++ if (pInfo)
++ *pInfo = nInfo;
++
++ rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
++ rtl_destroyTextToUnicodeConverter( hConverter );
++ return;
+ }
+- pScratch->length = len;
+- rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
+- return;
+ }
++
+ /* FIXME: we want a nice UTF-8 / alloca shortcut here */
+ }
+
+diff --git sal/textenc/tcvtbyte.c sal/textenc/tcvtbyte.c
+index be39b8e..ca5571e 100644
+--- sal/textenc/tcvtbyte.c
++++ sal/textenc/tcvtbyte.c
+@@ -643,6 +643,47 @@ sal_Size ImplCharToUnicode( const ImplTextConverterData* pData,
+
+ /* ----------------------------------------------------------------------- */
+
++sal_Size ImplUpperCharToUnicode( const ImplTextConverterData* pData,
++ void* pContext,
++ const sal_Char* pSrcBuf, sal_Size nSrcBytes,
++ sal_Unicode* pDestBuf, sal_Size nDestChars,
++ sal_uInt32 nFlags, sal_uInt32* pInfo,
++ sal_Size* pSrcCvtBytes )
++{
++ sal_uChar c;
++ sal_Unicode cConv;
++ const ImplByteConvertData* pConvertData = (const ImplByteConvertData*)pData;
++ sal_Unicode* pEndDestBuf;
++ const sal_Char* pEndSrcBuf;
++
++ (void) pContext; /* unused */
++ (void) nFlags; /* unused */
++
++ *pInfo = 0;
++ pEndDestBuf = pDestBuf+nDestChars;
++ pEndSrcBuf = pSrcBuf+nSrcBytes;
++ while ( pSrcBuf < pEndSrcBuf )
++ {
++ c = (sal_uChar)*pSrcBuf;
++ if (c < 0x80)
++ cConv = c;
++ else
++ // c <= 0xFF is implied.
++ cConv = pConvertData->mpToUniTab1[c - 0x80];
++
++ // No need to handle cConv == 0 since that never happens.
++
++ *pDestBuf = cConv;
++ pDestBuf++;
++ pSrcBuf++;
++ }
++
++ *pSrcCvtBytes = nSrcBytes - (pEndSrcBuf-pSrcBuf);
++ return (nDestChars - (pEndDestBuf-pDestBuf));
++}
++
++/* ----------------------------------------------------------------------- */
++
+ // Writes 0--2 characters to dest:
+ static int ImplConvertUnicodeCharToChar(
+ const ImplByteConvertData* pConvertData, sal_Unicode c, sal_Char * dest )
+diff --git sal/textenc/tcvtlat1.tab sal/textenc/tcvtlat1.tab
+index 4bc77f6..86e7b06 100644
+--- sal/textenc/tcvtlat1.tab
++++ sal/textenc/tcvtlat1.tab
+@@ -191,7 +191,7 @@ static ImplByteConvertData const aImplIBM437ByteCvtData =
+
+ static ImplTextEncodingData const aImplIBM437TextEncodingData
+ = { { &aImplIBM437ByteCvtData,
+- ImplCharToUnicode,
++ ImplUpperCharToUnicode,
+ ImplUnicodeToChar,
+ NULL,
+ NULL,
+@@ -325,7 +325,7 @@ static ImplByteConvertData const aImplIBM850ByteCvtData =
+
+ static ImplTextEncodingData const aImplIBM850TextEncodingData
+ = { { &aImplIBM850ByteCvtData,
+- ImplCharToUnicode,
++ ImplUpperCharToUnicode,
+ ImplUnicodeToChar,
+ NULL,
+ NULL,
+@@ -498,7 +498,7 @@ static ImplByteConvertData const aImplIBM860ByteCvtData =
+
+ static ImplTextEncodingData const aImplIBM860TextEncodingData
+ = { { &aImplIBM860ByteCvtData,
+- ImplCharToUnicode,
++ ImplUpperCharToUnicode,
+ ImplUnicodeToChar,
+ NULL,
+ NULL,
+@@ -673,7 +673,7 @@ static ImplByteConvertData const aImplIBM861ByteCvtData =
+
+ static ImplTextEncodingData const aImplIBM861TextEncodingData
+ = { { &aImplIBM861ByteCvtData,
+- ImplCharToUnicode,
++ ImplUpperCharToUnicode,
+ ImplUnicodeToChar,
+ NULL,
+ NULL,
+@@ -848,7 +848,7 @@ static ImplByteConvertData const aImplIBM863ByteCvtData =
+
+ static ImplTextEncodingData const aImplIBM863TextEncodingData
+ = { { &aImplIBM863ByteCvtData,
+- ImplCharToUnicode,
++ ImplUpperCharToUnicode,
+ ImplUnicodeToChar,
+ NULL,
+ NULL,
+@@ -1023,7 +1023,7 @@ static ImplByteConvertData const aImplIBM865ByteCvtData =
+
+ static ImplTextEncodingData const aImplIBM865TextEncodingData
+ = { { &aImplIBM865ByteCvtData,
+- ImplCharToUnicode,
++ ImplUpperCharToUnicode,
+ ImplUnicodeToChar,
+ NULL,
+ NULL,
+@@ -1563,7 +1563,7 @@ static ImplByteConvertData const aImplAPPLEICELANDByteCvtData =
+
+ static ImplTextEncodingData const aImplAPPLEICELANDTextEncodingData
+ = { { &aImplAPPLEICELANDByteCvtData,
+- ImplCharToUnicode,
++ ImplUpperCharToUnicode,
+ ImplUnicodeToChar,
+ NULL,
+ NULL,
+@@ -1710,7 +1710,7 @@ static ImplByteConvertData const aImplAPPLEROMANByteCvtData =
+
+ static ImplTextEncodingData const aImplAPPLEROMANTextEncodingData
+ = { { &aImplAPPLEROMANByteCvtData,
+- ImplCharToUnicode,
++ ImplUpperCharToUnicode,
+ ImplUnicodeToChar,
+ NULL,
+ NULL,
+diff --git sal/textenc/tenchelp.h sal/textenc/tenchelp.h
+index 16affcd..6c0a930 100644
+--- sal/textenc/tenchelp.h
++++ sal/textenc/tenchelp.h
+@@ -233,6 +233,11 @@ sal_Size ImplCharToUnicode( const ImplTextConverterData* pData, void* pContext,
+ const sal_Char* pSrcBuf, sal_Size nSrcBytes,
+ sal_Unicode* pDestBuf, sal_Size nDestChars,
+ sal_uInt32 nFlags, sal_uInt32* pInfo, sal_Size* pSrcCvtBytes );
++/** For those encodings only with unicode range of 0x80 to 0xFF. */
++sal_Size ImplUpperCharToUnicode( const ImplTextConverterData* pData, void* pContext,
++ const sal_Char* pSrcBuf, sal_Size nSrcBytes,
++ sal_Unicode* pDestBuf, sal_Size nDestChars,
++ sal_uInt32 nFlags, sal_uInt32* pInfo, sal_Size* pSrcCvtBytes );
+ sal_Size ImplUnicodeToChar( const ImplTextConverterData* pData, void* pContext,
+ const sal_Unicode* pSrcBuf, sal_Size nSrcChars,
+ sal_Char* pDestBuf, sal_Size nDestBytes,
More information about the ooo-build-commit
mailing list