Files
core/ASCOfficeDocxFile2/DocWrapper/DocxSerializer.cpp
Sergey.Konovalov 9ecab11286 конвертация shape через классы, а не dll; CAtlArray->std::vector для некоторых классов pptx
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@58362 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-20 23:14:45 +03:00

316 lines
11 KiB
C++
Raw Blame History

#include "DocxSerializer.h"
#ifdef _WIN32
#include <atlbase.h>
#include <atlstr.h>
#else
#include "../../Common/DocxFormat/Source/Base/ASCString.h"
#endif
#include "../../DesktopEditor/common/Directory.h"
#include "../../DesktopEditor/common/File.h"
#include "../BinWriter/BinWriters.h"
#include "../BinReader/Readers.h"
#ifndef _WIN32
#include "../../DesktopEditor/common/Types.h"
#endif
int BinDocxRW::g_nCurFormatVersion = 0;
BinDocxRW::CDocxSerializer::CDocxSerializer()
{
m_oBinaryFileWriter = NULL;
m_pCurFileWriter = NULL;
m_bIsNoBase64Save = false;
m_bSaveChartAsImg = false;
}
bool BinDocxRW::CDocxSerializer::saveToFile(std::wstring& sSrcFileName, std::wstring& sDstPath, std::wstring& sXMLOptions)
{
//create mediadir
OOX::CPath path(std_string2string(sSrcFileName));
CString mediaDir = path.GetDirectory() + _T("media\\");
NSDirectory::CreateDirectory(string2std_string(mediaDir));
Streams::CBuffer oBuffer;
oBuffer.Create(BUFFER_GROW_SIZE, BUFFER_GROW_SIZE);
Streams::CBufferedStream oBufferedStream;
oBufferedStream.SetBuffer(&oBuffer);
#ifdef _WIN32
DocWrapper::FontProcessor fp;
fp.setFontDir(std_string2string(m_sFontDir));
PPTXFile::IOfficeFontPicker* pFontPicker = NULL;
CoCreateInstance(__uuidof(PPTXFile::COfficeFontPicker), NULL, CLSCTX_ALL, __uuidof(PPTXFile::IOfficeFontPicker), (void**)(&pFontPicker));
BSTR bstrFontDir1 = std_string2string(m_sFontDir).AllocSysString();
pFontPicker->Init(bstrFontDir1);
SysFreeString(bstrFontDir1);
NSFontCutter::CEmbeddedFontsManager* pEmbeddedFontsManager = NULL;
if(false == std_string2string(m_sEmbeddedFontsDir).IsEmpty())
{
NSDirectory::CreateDirectory(m_sEmbeddedFontsDir);
BSTR bstrEmbeddedFontsDirectory = std_string2string(m_sEmbeddedFontsDir).AllocSysString();
pFontPicker->SetEmbeddedFontsDirectory(bstrEmbeddedFontsDirectory);
SysFreeString(bstrEmbeddedFontsDirectory);
VARIANT vt;
pFontPicker->GetAdditionalParam(_T("NativeCutter"), &vt);
pEmbeddedFontsManager = (NSFontCutter::CEmbeddedFontsManager*)vt.pvRecord;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
pEmbeddedFontsManager->CheckString(CString(_T("abcdefghijklmnopqrstuvwxyz")));
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
pEmbeddedFontsManager->CheckFont(_T("Wingdings 3"), fp.getFontManager());
pEmbeddedFontsManager->CheckFont(_T("Arial"), fp.getFontManager());
//pEmbeddedFontsManager <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
}
NSBinPptxRW::CDrawingConverter oDrawingConverter;
BSTR bstrFontDir = std_string2string(m_sFontDir).AllocSysString();
oDrawingConverter.SetFontDir(bstrFontDir);
SysFreeString(bstrFontDir);
VARIANT vt;
vt.vt = VT_UNKNOWN;
vt.punkVal = pFontPicker;
oDrawingConverter.SetAdditionalParam(_T("FontPicker"), vt);
oDrawingConverter.SetMainDocument(this);
BSTR bstrMediaDir = mediaDir.AllocSysString();
oDrawingConverter.SetMediaDstPath(bstrMediaDir);
SysFreeString(bstrMediaDir);
ParamsWriter oParamsWriter(oBufferedStream, fp, &oDrawingConverter, pEmbeddedFontsManager);
m_oBinaryFileWriter = new BinaryFileWriter(oParamsWriter);
m_oBinaryFileWriter->intoBindoc(std_string2string(sDstPath));
#endif
BYTE* pbBinBuffer = oBufferedStream.GetBuffer();
int nBinBufferLen = oBufferedStream.GetPosition();
if (m_bIsNoBase64Save)
{
NSFile::CFileBinary oFile;
oFile.CreateFileW(sSrcFileName);
oFile.WriteFile(pbBinBuffer, nBinBufferLen);
oFile.CloseFile();
}
else
{
int nBase64BufferLen = Base64::Base64EncodeGetRequiredLength(nBinBufferLen, Base64::B64_BASE64_FLAG_NOCRLF);
BYTE* pbBase64Buffer = new BYTE[nBase64BufferLen];
if(TRUE == Base64::Base64Encode(pbBinBuffer, nBinBufferLen, (LPSTR)pbBase64Buffer, &nBase64BufferLen, Base64::B64_BASE64_FLAG_NOCRLF))
{
NSFile::CFileBinary oFile;
oFile.CreateFileW(sSrcFileName);
oFile.WriteStringUTF8(string2std_string(m_oBinaryFileWriter->WriteFileHeader(nBinBufferLen)));
oFile.WriteFile(pbBase64Buffer, nBase64BufferLen);
oFile.CloseFile();
}
}
RELEASEOBJECT(m_oBinaryFileWriter);
RELEASEINTERFACE(pFontPicker);
return true;
}
bool BinDocxRW::CDocxSerializer::loadFromFile(std::wstring& sSrcFileName, std::wstring& sDstPath, std::wstring& sXMLOptions, std::wstring& sThemePath, std::wstring& sMediaPath)
{
bool bResultOk = false;
NSFile::CFileBinary oFile;
if(oFile.OpenFile(sSrcFileName))
{
DWORD nBase64DataSize = 0;
BYTE* pBase64Data = new BYTE[oFile.GetFileSize()];
oFile.ReadFile(pBase64Data, oFile.GetFileSize(), nBase64DataSize);
oFile.CloseFile();
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool bValidFormat = false;
CString sSignature(g_sFormatSignature);
int nSigLength = sSignature.GetLength();
if(nBase64DataSize > nSigLength)
{
CStringA sCurSig((char*)pBase64Data, nSigLength);
if((CStringA)sSignature == sCurSig)
{
bValidFormat = true;
}
}
if(bValidFormat)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> base64
int nIndex = nSigLength;
int nType = 0;
CStringA version = "";
CStringA dst_len = "";
while (true)
{
nIndex++;
BYTE _c = pBase64Data[nIndex];
if (_c == ';')
{
if(0 == nType)
{
nType = 1;
continue;
}
else
{
nIndex++;
break;
}
}
if(0 == nType)
version.AppendChar(_c);
else
dst_len.AppendChar(_c);
}
int nDataSize = atoi(dst_len);
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = nDataSize;
LPSAFEARRAY pArray = SafeArrayCreate(VT_UI1, 1, rgsabound);
if(FALSE != Base64::Base64Decode((LPCSTR)(pBase64Data + nIndex), nBase64DataSize - nIndex, (BYTE*)pArray->pvData, &nDataSize))
{
Streams::CBuffer oBuffer;
Streams::CBufferedStream oBufferedStream;
oBufferedStream.SetBuffer(&oBuffer);
oBufferedStream.Create((BYTE*)pArray->pvData, nDataSize);
int nVersion = g_nFormatVersion;
if(version.GetLength() > 0)
{
version = version.Right(version.GetLength() - 1);
int nTempVersion = atoi(version);
if(0 != nTempVersion)
{
g_nCurFormatVersion = nVersion = nTempVersion;
}
}
NSBinPptxRW::CDrawingConverter oDrawingConverter;
oDrawingConverter.SetMainDocument(this);
BSTR bstrMediaPath = std_string2string(sMediaPath).AllocSysString();
oDrawingConverter.SetMediaDstPath(bstrMediaPath);
SysFreeString(bstrMediaPath);
m_pCurFileWriter = new Writers::FileWriter(std_string2string(sDstPath), std_string2string(m_sFontDir), nVersion, m_bSaveChartAsImg, &oDrawingConverter, pArray, std_string2string(sThemePath));
//<2F><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TCHAR tFolder[256];
TCHAR tDrive[256];
_tsplitpath( sSrcFileName.c_str(), tDrive, tFolder, NULL, NULL );
CString sFolder = CString(tFolder);
CString sDrive = CString(tDrive);
CString sFileInDir = sDrive + sFolder;
VARIANT var;
var.vt = VT_BSTR;
var.bstrVal = sFileInDir.AllocSysString();
oDrawingConverter.SetAdditionalParam(L"SourceFileDir", var);
RELEASESYSSTRING(var.bstrVal);
BinaryFileReader oBinaryFileReader(sFileInDir, oBufferedStream, *m_pCurFileWriter);
oBinaryFileReader.ReadFile();
VARIANT vt;
oDrawingConverter.GetAdditionalParam(_T("ContentTypes"), &vt);
if(VT_BSTR == vt.vt)
m_pCurFileWriter->m_oContentTypesWriter.AddOverrideRaw(CString(vt.bstrVal));
m_pCurFileWriter->m_oCommentsWriter.Write();
m_pCurFileWriter->m_oChartWriter.Write();
m_pCurFileWriter->m_oStylesWriter.Write();
m_pCurFileWriter->m_oNumberingWriter.Write();
m_pCurFileWriter->m_oFontTableWriter.Write();
m_pCurFileWriter->m_oHeaderFooterWriter.Write();
//Setting <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> HeaderFooter, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> evenAndOddHeaders
m_pCurFileWriter->m_oSettingWriter.Write();
//Document <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> HeaderFooter, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> sectPr
m_pCurFileWriter->m_oDocumentWriter.Write();
//Rels <20> ContentTypes <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>
//m_pCurFileWriter->m_oDocumentRelsWriter.Write(_T("document.xml.rels"));
m_pCurFileWriter->m_oContentTypesWriter.Write();
//CSerializer oSerializer = CSerializer();
//if(false != oSerializer.Write(oBufferedStream, sDirectoryOut))
//{
bResultOk = true;
//}
}
RELEASEARRAY(pArray);
}
RELEASEARRAYOBJECTS(pBase64Data);
}
return bResultOk;
}
bool BinDocxRW::CDocxSerializer::getXmlContent(unsigned char* pBinaryObj, long lSize, long lStart, long lLength, std::wstring& sOutputXml)
{
Streams::CBuffer oBuffer;
Streams::CBufferedStream oBufferedStream;
oBufferedStream.SetBuffer(&oBuffer);
oBufferedStream.Create(pBinaryObj, lSize);
oBufferedStream.Seek(lStart);
long nLength = oBufferedStream.ReadLong();
Writers::ContentWriter oTempContentWriter;
BinDocxRW::Binary_DocumentTableReader oBinary_DocumentTableReader(oBufferedStream, *m_pCurFileWriter, oTempContentWriter, NULL);
int res = oBinary_DocumentTableReader.Read1(nLength, &BinDocxRW::Binary_DocumentTableReader::ReadDocumentContent, &oBinary_DocumentTableReader, NULL);
sOutputXml = oTempContentWriter.m_oContent.GetData().GetString();
return true;
}
bool BinDocxRW::CDocxSerializer::getBinaryContent(std::wstring& bsTxContent, unsigned char** ppBinary, long &lDataSize)
{
if(NULL == m_oBinaryFileWriter)
return false;
Streams::CBuffer oBuffer;
oBuffer.Create(BUFFER_GROW_SIZE, BUFFER_GROW_SIZE);
Streams::CBufferedStream oBufferedStream;
oBufferedStream.SetBuffer(&oBuffer);
XmlUtils::CXmlLiteReader oReader;
oReader.FromString(std_string2string(bsTxContent));
oReader.ReadNextNode();//v:textbox
CString sRootName = oReader.GetName();
if(_T("v:textbox") == sRootName)
oReader.ReadNextNode();//w:txbxContent
OOX::Logic::CSdtContent oSdtContent;
oSdtContent.fromXML(oReader);
BinDocxRW::ParamsWriter oCurParamsWriter(m_oBinaryFileWriter->m_oParamsWriter);
BinDocxRW::ParamsWriter oParamsWriter(oBufferedStream, oCurParamsWriter.m_oFontProcessor, oCurParamsWriter.m_pOfficeDrawingConverter, oCurParamsWriter.m_pEmbeddedFontsManager);
oParamsWriter.m_poTheme = oCurParamsWriter.m_poTheme;
oParamsWriter.m_oSettings = oCurParamsWriter.m_oSettings;
oParamsWriter.m_pCurRels = oCurParamsWriter.m_pCurRels;
oParamsWriter.m_sCurDocumentPath = oCurParamsWriter.m_sCurDocumentPath;
BinDocxRW::BinaryCommonWriter oBinaryCommonWriter(oParamsWriter);
int nCurPos = oBinaryCommonWriter.WriteItemWithLengthStart();
BinDocxRW::BinaryDocumentTableWriter oBinaryDocumentTableWriter(oParamsWriter, BinDocxRW::ParamsDocumentWriter(oParamsWriter.m_pCurRels, oParamsWriter.m_sCurDocumentPath), NULL, NULL);
oBinaryDocumentTableWriter.WriteDocumentContent(oSdtContent.m_arrItems);
oBinaryCommonWriter.WriteItemWithLengthEnd(nCurPos);
if (NULL != ppBinary)
{
lDataSize = oBufferedStream.GetPosition();
*ppBinary = new unsigned char[lDataSize];
BYTE* pDataS = oBufferedStream.GetBuffer();
memcpy(*ppBinary, pDataS, lDataSize);
}
return true;
}
void BinDocxRW::CDocxSerializer::setFontDir(std::wstring& sFontDir)
{
m_sFontDir = sFontDir;
}
void BinDocxRW::CDocxSerializer::setEmbeddedFontsDir(std::wstring& sEmbeddedFontsDir)
{
m_sEmbeddedFontsDir = sEmbeddedFontsDir;
}
void BinDocxRW::CDocxSerializer::setIsNoBase64Save(bool bIsNoBase64Save)
{
m_bIsNoBase64Save = bIsNoBase64Save;
}
void BinDocxRW::CDocxSerializer::setSaveChartAsImg(bool bSaveChartAsImg)
{
m_bSaveChartAsImg = bSaveChartAsImg;
}