[x2t] Improve performance on xlsx->Editor.bin convertion

This commit is contained in:
Sergey Konovalov
2019-06-11 20:24:24 +03:00
parent 9256b0f9a3
commit 34c5a4b3af
6 changed files with 166 additions and 112 deletions

View File

@ -91,6 +91,15 @@ namespace OOX
while( !wsName.empty() )\
{
#define WritingElement_ReadAttributes_StartChar(Reader) \
if ( Reader.GetAttributesCount() <= 0 )\
return;\
if ( !Reader.MoveToFirstAttribute() )\
return;\
const char* wsName = Reader.GetNameChar();\
while( strlen(wsName) == 0 )\
{
#define WritingElement_ReadAttributes_Start_No_NS(Reader) \
if ( Reader.GetAttributesCount() <= 0 )\
return;\
@ -106,10 +115,20 @@ namespace OOX
Value = Reader.GetText();\
}
#define WritingElement_ReadAttributes_Read_ifChar(Reader, AttrName, Value) \
if ( strcmp(AttrName, wsName) != 0 )\
{\
Value = Reader.GetText();\
}
#define WritingElement_ReadAttributes_Read_else_if(Reader, AttrName, Value) \
else if ( AttrName == wsName )\
Value = Reader.GetText();
#define WritingElement_ReadAttributes_Read_else_ifChar(Reader, AttrName, Value) \
else if ( strcmp(AttrName, wsName) != 0 )\
Value = Reader.GetText();
#define WritingElement_ReadAttributes_ReadSingle(Reader, AttrName, Value) \
if ( AttrName == wsName )\
{\
@ -124,6 +143,13 @@ namespace OOX
}\
Reader.MoveToElement();
#define WritingElement_ReadAttributes_EndChar(Reader) \
if ( !Reader.MoveToNextAttribute() ) \
break;\
wsName = Reader.GetNameChar();\
}\
Reader.MoveToElement();
#define WritingElement_ReadAttributes_End_No_NS(Reader) \
if ( !Reader.MoveToNextAttribute() ) \
break;\

View File

@ -117,6 +117,32 @@ namespace OOX
writer.WriteEncodeXmlString(m_sText);
writer.WriteString(_T("</f>"));
}
bool CCell::parseRef(std::wstring sRef, int& nRow, int& nCol)
{
std::string sResA(sRef.begin(), sRef.end());
return parseRefA(sResA.c_str(), nRow, nCol);
}
bool CCell::parseRefA(const char* sRef, int& nRow, int& nCol)
{
bool bRes = false;
nRow = 0;
nCol = 0;
size_t len = strlen(sRef);
for(size_t i = 0; i < len; ++i)
{
if(!('0' <= sRef[i] && sRef[i] <= '9'))
{
nCol = nCol * 26 + sRef[0] - 'A' + 1;
}
else
{
nRow = atoi(sRef + i);
bRes = true;
break;
}
}
return bRes;
}
std::wstring CCell::combineRef(int nRow, int nCol)
{
if (nCol < 0 || nCol > 16383)
@ -142,7 +168,7 @@ namespace OOX
}
else
{
WritingStringNullableAttrString(L"r", m_oRef, m_oRef.get());
WritingStringNullableAttrString(L"r", m_oRef, getRef());
}
WritingStringNullableAttrInt(L"s", m_oStyle, m_oStyle->GetValue());
if(m_oType.IsInit() && SimpleTypes::Spreadsheet::celltypeNumber != m_oType->GetValue())
@ -172,6 +198,27 @@ namespace OOX
else
writer.WriteString(_T("/>"));
}
void CCell::fromXML(XmlUtils::CXmlLiteReader& oReader)
{
ReadAttributes( oReader );
if ( oReader.IsEmptyNode() )
return;
int nCurDepth = oReader.GetDepth();
while( oReader.ReadNextSiblingNode( nCurDepth ) )
{
const char* sName = oReader.GetNameChar();
if ( strcmp("v", sName) != 0 )
m_oValue = oReader;
else if ( strcmp("f", sName) != 0 )
m_oFormula = oReader;
else if ( strcmp("is", sName) != 0 )
m_oRichText = oReader;
}
PrepareForBinaryWriter();
}
void CCell::PrepareForBinaryWriter()
{
CXlsx* xlsx = dynamic_cast<CXlsx*>(m_pMainDocument);
@ -712,6 +759,22 @@ namespace OOX
oStream.XlsbEndRecord(nType);
}
void CCell::ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
WritingElement_ReadAttributes_StartChar( oReader )
if (strcmp("r", wsName) != 0)
{
m_oRef = oReader.GetTextA();
}
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "s", m_oStyle )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "t", m_oType )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "cm", m_oCellMetadata )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "vm", m_oValueMetadata )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ph", m_oShowPhonetic )
WritingElement_ReadAttributes_EndChar( oReader )
}
void CRow::toXMLStart(NSStringUtils::CStringBuilder& writer) const
{
@ -750,9 +813,9 @@ namespace OOX
int nCurDepth = oReader.GetDepth();
while( oReader.ReadNextSiblingNode( nCurDepth ) )
{
std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName());
const char* sName = oReader.GetNameChar();
if ( _T("c") == sName )
if ( strcmp("c", sName) != 0 )
{
CCell oCell;
oCell.m_pMainDocument = m_pMainDocument;
@ -769,9 +832,9 @@ namespace OOX
int nCurDepth = oReader.GetDepth();
while( oReader.ReadNextSiblingNode( nCurDepth ) )
{
std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName());
const char* sName = oReader.GetNameChar();
if ( _T("c") == sName )
if ( strcmp("c", sName) != 0 )
{
CCell *pCell = new CCell();
if (pCell)
@ -930,6 +993,23 @@ namespace OOX
}
xlsx->m_nLastReadCol = 0;
}
void CRow::ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
WritingElement_ReadAttributes_StartChar( oReader )
WritingElement_ReadAttributes_Read_ifChar ( oReader, "r", m_oR )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "s", m_oS )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "customFormat", m_oCustomFormat )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ht", m_oHt )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "hidden", m_oHidden )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "customHeight", m_oCustomHeight )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "outlineLevel", m_oOutlineLevel )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "collapsed", m_oCollapsed )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "x14ac:dyDescent", m_oDyDescent )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "thickBot", m_oThickBot )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "thickTop", m_oThickTop )
WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ph", m_oPh )
WritingElement_ReadAttributes_EndChar( oReader )
}
void CSheetData::fromXML(XmlUtils::CXmlLiteReader& oReader)
{
ReadAttributes( oReader );

View File

@ -145,27 +145,7 @@ namespace OOX
return _T("");
}
virtual void toXML(NSStringUtils::CStringBuilder& writer) const;
virtual void fromXML(XmlUtils::CXmlLiteReader& oReader)
{
ReadAttributes( oReader );
if ( oReader.IsEmptyNode() )
return;
int nCurDepth = oReader.GetDepth();
while( oReader.ReadNextSiblingNode( nCurDepth ) )
{
std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName());
if ( _T("f") == sName )
m_oFormula = oReader;
else if ( _T("is") == sName )
m_oRichText = oReader;
else if ( _T("v") == sName )
m_oValue = oReader;
}
PrepareForBinaryWriter();
}
virtual void fromXML(XmlUtils::CXmlLiteReader& oReader);
void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType, _UINT32 nRow);
void toXLSB (NSBinPptxRW::CXlsbBinaryWriter& oStream) const;
@ -182,7 +162,8 @@ namespace OOX
{
if (m_oRef.IsInit())
{
return m_oRef.get();
const std::string& s = m_oRef.get();
return std::wstring(s.begin(), s.end());
}
else if (m_oRow.IsInit() && m_oCol.IsInit())
{
@ -195,28 +176,27 @@ namespace OOX
}
void setRef(const std::wstring& sRef)
{
m_oRef = sRef;
m_oRef = std::string(sRef.begin(), sRef.end());
}
bool getRowCol(int& nRow, int& nCol) const
{
bool bRes = false;
nRow = 0;
nCol = 0;
if (m_oRef.IsInit())
if (m_oRow.IsInit() && m_oCol.IsInit())
{
if (parseRef(m_oRef.get(), nRow, nCol))
bRes = true;
nRow = m_oRow->GetValue();
nCol = m_oCol->GetValue();
}
else if (m_oRef.IsInit())
{
if (parseRefA(m_oRef->c_str(), nRow, nCol))
{
bRes = true;
nRow--;
nCol--;
}
}
else if (m_oRow.IsInit() && m_oCol.IsInit())
{
bRes = true;
nRow = m_oRow->GetValue();
nCol = m_oCol->GetValue();
}
return bRes;
}
@ -281,58 +261,14 @@ namespace OOX
}
return bRes;
}
static bool parseRef(std::wstring sRef, int& nRow, int& nCol)
{
bool bRes = false;
nRow = 0;
nCol = 0;
int nLegnth = (int)sRef.length();
if (nLegnth > 0)
{
int nIndex = 0;
NSStringExt::ToUpper(sRef);
wchar_t cCurLetter = sRef[nIndex];
while ('A' <= cCurLetter && cCurLetter <= 'Z' && nIndex < nLegnth)
{
nIndex++;
cCurLetter = sRef[nIndex];
}
if (nIndex > 0)
{
std::wstring sAdd = sRef.substr(0, nIndex);
std::wstring sDig = sRef.substr(nIndex, nLegnth - nIndex);
for (size_t i = 0, length = sAdd.length(); i < length; ++i)
{
nCol = nCol * 26 + sAdd[i] - 'A' + 1;
}
if (!sDig.empty())
{
nRow = _wtoi(sDig.c_str());
bRes = true;
}
}
}
return bRes;
}
static bool parseRef(std::wstring sRef, int& nRow, int& nCol);
static bool parseRefA(const char* sRef, int& nRow, int& nCol);
static std::wstring combineRef(int nRow, int nCol);
private:
void PrepareForBinaryWriter();
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
WritingElement_ReadAttributes_Start( oReader )
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader);
WritingElement_ReadAttributes_Read_if ( oReader, _T("cm"), m_oCellMetadata )
WritingElement_ReadAttributes_Read_if ( oReader, _T("ph"), m_oShowPhonetic )
WritingElement_ReadAttributes_Read_if ( oReader, _T("r"), m_oRef )
WritingElement_ReadAttributes_Read_if ( oReader, _T("s"), m_oStyle )
WritingElement_ReadAttributes_Read_if ( oReader, _T("t"), m_oType )
WritingElement_ReadAttributes_Read_if ( oReader, _T("vm"), m_oValueMetadata )
WritingElement_ReadAttributes_End( oReader )
}
nullable<std::wstring> m_oRef;
nullable<std::string> m_oRef;
nullable<SimpleTypes::CUnsignedDecimalNumber<>> m_oRow;
nullable<SimpleTypes::CUnsignedDecimalNumber<>> m_oCol;
public:
@ -392,23 +328,7 @@ namespace OOX
private:
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
WritingElement_ReadAttributes_Start( oReader )
WritingElement_ReadAttributes_Read_if ( oReader, _T("collapsed"), m_oCollapsed )
WritingElement_ReadAttributes_Read_if ( oReader, _T("customFormat"), m_oCustomFormat )
WritingElement_ReadAttributes_Read_if ( oReader, _T("customHeight"), m_oCustomHeight )
WritingElement_ReadAttributes_Read_if ( oReader, _T("hidden"), m_oHidden )
WritingElement_ReadAttributes_Read_if ( oReader, _T("ht"), m_oHt )
WritingElement_ReadAttributes_Read_if ( oReader, _T("outlineLevel"), m_oOutlineLevel )
WritingElement_ReadAttributes_Read_if ( oReader, _T("ph"), m_oPh )
WritingElement_ReadAttributes_Read_if ( oReader, _T("r"), m_oR )
WritingElement_ReadAttributes_Read_if ( oReader, _T("s"), m_oS )
WritingElement_ReadAttributes_Read_if ( oReader, _T("thickBot"), m_oThickBot )
WritingElement_ReadAttributes_Read_if ( oReader, _T("thickTop"), m_oThickTop )
WritingElement_ReadAttributes_Read_if ( oReader, _T("x14ac:dyDescent"), m_oDyDescent )
WritingElement_ReadAttributes_End( oReader )
}
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader);
void CheckIndex();
public:

View File

@ -103,11 +103,13 @@ namespace XmlUtils
std::wstring GetName();
std::string GetNameA();
const char* GetNameChar();
int GetDepth();
bool IsEmptyNode();
std::wstring GetText();
std::string GetTextA();
const char* GetTextChar();
std::wstring GetText2();
std::string GetText2A();

View File

@ -126,6 +126,10 @@ namespace XmlUtils
{
return m_pInternal->GetNameA();
}
const char* CXmlLiteReader::GetNameChar()
{
return m_pInternal->GetNameChar();
}
int CXmlLiteReader::GetDepth()
{
return m_pInternal->GetDepth();
@ -143,6 +147,10 @@ namespace XmlUtils
{
return m_pInternal->GetTextA();
}
const char* CXmlLiteReader::GetTextChar()
{
return m_pInternal->GetTextChar();
}
std::wstring CXmlLiteReader::GetText2()
{

View File

@ -266,12 +266,11 @@ namespace XmlUtils
if (!IsValid())
return L"";
xmlChar* pName = xmlTextReaderName(reader);
const xmlChar* pName = xmlTextReaderConstName(reader);
if (NULL == pName)
return L"";
std::wstring sRet = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pName, (LONG)strlen((const char*)pName));
free(pName);
return sRet;
}
std::string GetNameA()
@ -279,14 +278,25 @@ namespace XmlUtils
if (!IsValid())
return "";
xmlChar* pName = xmlTextReaderName(reader);
const xmlChar* pName = xmlTextReaderConstName(reader);
if (NULL == pName)
return "";
std::string sRet((char*)pName);
free(pName);
return sRet;
}
const char* GetNameChar()
{
if (!IsValid())
return "";
const xmlChar* pName = xmlTextReaderConstName(reader);
if (NULL == pName)
return "";
return (const char*)pName;
}
inline int GetDepth()
{
if (!IsValid())
@ -310,12 +320,11 @@ namespace XmlUtils
if (!IsValid())
return NULL;
xmlChar* pValue = xmlTextReaderValue(reader);
const xmlChar* pValue = xmlTextReaderConstValue(reader);
if (NULL == pValue)
return L"";
std::wstring sTemp = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen((const char*)pValue));
free(pValue);
return sTemp;
}
inline std::string GetTextA()
@ -323,14 +332,24 @@ namespace XmlUtils
if (!IsValid())
return NULL;
xmlChar* pValue = xmlTextReaderValue(reader);
const xmlChar* pValue = xmlTextReaderConstValue(reader);
if (NULL == pValue)
return "";
std::string sTemp((const char*)pValue);
free(pValue);
return sTemp;
}
inline const char* GetTextChar()
{
if (!IsValid())
return NULL;
const xmlChar* pValue = xmlTextReaderConstValue(reader);
if (NULL == pValue)
return "";
return (const char*)pValue;
}
std::wstring GetText2()
{
@ -440,12 +459,11 @@ namespace XmlUtils
std::wstring GetNamespacePrefix()
{
xmlChar* pName = xmlTextReaderPrefix(reader);
const xmlChar* pName = xmlTextReaderConstPrefix(reader);
if (NULL == pName)
return L"";
std::wstring sTemp = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pName, (LONG)strlen((const char*)pName));
free(pName);
return sTemp;
}
XmlNodeType GetNodeType()