Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
core/ASCOfficePPTXFile/Editor/BinaryFileReaderWriter.cpp
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
2058 lines (1803 sloc)
61.4 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * (c) Copyright Ascensio System SIA 2010-2019 | |
| * | |
| * This program is a free software product. You can redistribute it and/or | |
| * modify it under the terms of the GNU Affero General Public License (AGPL) | |
| * version 3 as published by the Free Software Foundation. In accordance with | |
| * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect | |
| * that Ascensio System SIA expressly excludes the warranty of non-infringement | |
| * of any third-party rights. | |
| * | |
| * This program is distributed WITHOUT ANY WARRANTY; without even the implied | |
| * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For | |
| * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html | |
| * | |
| * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha | |
| * street, Riga, Latvia, EU, LV-1050. | |
| * | |
| * The interactive user interfaces in modified source and object code versions | |
| * of the Program must display Appropriate Legal Notices, as required under | |
| * Section 5 of the GNU AGPL version 3. | |
| * | |
| * Pursuant to Section 7(b) of the License you must retain the original Product | |
| * logo when distributing the program. Pursuant to Section 7(e) we decline to | |
| * grant you any rights under trademark law for use of our trademarks. | |
| * | |
| * All the Product's GUI elements, including illustrations and icon sets, as | |
| * well as technical writing content are licensed under the terms of the | |
| * Creative Commons Attribution-ShareAlike 4.0 International. See the License | |
| * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode | |
| * | |
| */ | |
| #include "BinaryFileReaderWriter.h" | |
| #include "BinReaderWriterDefines.h" | |
| #include "../../Common/DocxFormat/Source/Base/Nullable.h" | |
| #include "../../Common/DocxFormat/Source/DocxFormat/WritingElement.h" | |
| #include "../../Common/DocxFormat/Source/DocxFormat/Media/OleObject.h" | |
| #include "../../Common/DocxFormat/Source/DocxFormat/Media/ActiveX.h" | |
| #include "../../Common/DocxFormat/Source/DocxFormat/Media/Video.h" | |
| #include "../../Common/DocxFormat/Source/DocxFormat/Media/Audio.h" | |
| #include "../../Common/DocxFormat/Source/DocxFormat/Media/VbaProject.h" | |
| #include "../../Common/DocxFormat/Source/DocxFormat/Media/JsaProject.h" | |
| #include "../../Common/Base64.h" | |
| #include "./imagemanager.h" | |
| #include "./XmlWriter.h" | |
| #include "./FontPicker.h" | |
| #include "../../ASCOfficeDocxFile2/DocWrapper/DocxSerializer.h" | |
| #include "../../DesktopEditor/common/File.h" | |
| #include "../../DesktopEditor/common/Directory.h" | |
| #include "../PPTXFormat/FileContainer.h" | |
| #include <iostream> | |
| #define BYTE_SIZEOF sizeof(BYTE) | |
| #define UINT16_SIZEOF sizeof(_UINT16) | |
| #define UINT32_SIZEOF sizeof(_UINT32) | |
| #define DOUBLE_SIZEOF sizeof(double) | |
| #define CHAR_SIZEOF sizeof(CHAR) | |
| #define INT16_SIZEOF sizeof(_INT16) | |
| #define INT32_SIZEOF sizeof(_INT32) | |
| #define INT64_SIZEOF sizeof(_INT64) | |
| #define DOUBLE_MAIN 10000 | |
| #if defined(_WIN32) || defined (_WIN64) | |
| #include "../../Common/DocxFormat/Source/Base/unicode_util.h" | |
| #endif | |
| namespace NSBinPptxRW | |
| { | |
| template <typename T,unsigned S> | |
| inline unsigned arraysize(const T (&v)[S]) { return S; } | |
| CCommonWriter::CCommonWriter() | |
| { | |
| m_pNativePicker = NULL; | |
| m_pFontPicker = NULL; | |
| m_bDeleteFontPicker = true; | |
| m_pMediaManager = new NSShapeImageGen::CMediaManager(); | |
| } | |
| CCommonWriter::~CCommonWriter() | |
| { | |
| m_pNativePicker = NULL; | |
| if(m_bDeleteFontPicker) | |
| RELEASEOBJECT(m_pFontPicker); | |
| RELEASEOBJECT(m_pMediaManager); | |
| } | |
| void CCommonWriter::CreateFontPicker(COfficeFontPicker* pPicker) | |
| { | |
| if(m_bDeleteFontPicker) | |
| RELEASEOBJECT(m_pFontPicker); | |
| m_pNativePicker = NULL; | |
| if (pPicker != NULL) | |
| { | |
| m_pFontPicker = pPicker; | |
| m_bDeleteFontPicker = false; | |
| } | |
| else | |
| { | |
| m_pFontPicker = new COfficeFontPicker(); | |
| m_bDeleteFontPicker = true; | |
| } | |
| m_pNativePicker = m_pFontPicker->GetNativePicker(); | |
| } | |
| void CCommonWriter::CheckFontPicker() | |
| { | |
| if (NULL == m_pFontPicker) | |
| CreateFontPicker(NULL); | |
| } | |
| CImageManager2::CImageManager2() : m_mapImages(), m_lIndexNextImage(0), m_lIndexCounter(0) | |
| { | |
| m_nDocumentType = XMLWRITER_DOC_TYPE_PPTX; | |
| m_pContentTypes = new OOX::CContentTypes(); | |
| } | |
| CImageManager2::~CImageManager2() | |
| { | |
| delete m_pContentTypes; | |
| } | |
| void CImageManager2::Clear() | |
| { | |
| m_mapImages.clear(); | |
| m_lIndexNextImage = 0; | |
| m_lIndexCounter = 0; | |
| } | |
| void CImageManager2::SetDstFolder(const std::wstring& strDst) | |
| { | |
| m_strDstFolder = strDst; | |
| m_strDstMedia = m_strDstFolder + FILE_SEPARATOR_STR + _T("media"); | |
| m_strDstEmbed = m_strDstFolder + FILE_SEPARATOR_STR + _T("embeddings"); | |
| NSDirectory::CreateDirectory(m_strDstMedia); | |
| NSDirectory::CreateDirectory(m_strDstEmbed); | |
| } | |
| std::wstring CImageManager2::GetDstFolder() | |
| { | |
| return m_strDstFolder; | |
| } | |
| void CImageManager2::SetDstMedia(const std::wstring& strDst) | |
| { | |
| m_strDstMedia = strDst; | |
| } | |
| std::wstring CImageManager2::GetDstMedia() | |
| { | |
| return m_strDstMedia; | |
| } | |
| void CImageManager2::SetDstEmbed(const std::wstring& strDst) | |
| { | |
| m_strDstEmbed = strDst; | |
| } | |
| std::wstring CImageManager2::GetDstEmbed() | |
| { | |
| return m_strDstEmbed; | |
| } | |
| int CImageManager2::IsDisplayedImage(const std::wstring& strInput) | |
| { | |
| int nRes = 0; | |
| //шаблон display[N]image.ext | |
| std::wstring sFind1 = _T("display"); | |
| int nIndex1 = (int)strInput.find(sFind1); | |
| if(-1 != nIndex1) | |
| { | |
| if(nIndex1 + sFind1.length() < strInput.length()) | |
| { | |
| wchar_t cRes1 = strInput[nIndex1 + sFind1.length()]; | |
| if('1' <= cRes1 && cRes1 <= '9') | |
| { | |
| wchar_t cRes2 = strInput[nIndex1 + sFind1.length() + 1]; | |
| int nImageIndex = nIndex1 + (int)sFind1.length() + 1; | |
| if (std::wstring::npos != strInput.find(_T("image"), nImageIndex)) | |
| { | |
| nRes = cRes1 - '0'; | |
| if('0' <= cRes2 && cRes2 <= '9') | |
| { | |
| nRes = nRes * 10 + (cRes2 - '0'); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return nRes; | |
| } | |
| _imageManager2Info CImageManager2::GenerateMedia(const std::wstring& strInput) | |
| { | |
| std::map<std::wstring, _imageManager2Info>::const_iterator pPair = m_mapImages.find(strInput); | |
| if (pPair != m_mapImages.end()) | |
| { | |
| return pPair->second; | |
| } | |
| _imageManager2Info oImageManagerInfo = GenerateMediaExec(strInput); | |
| m_mapImages[strInput] = oImageManagerInfo; | |
| return oImageManagerInfo; | |
| } | |
| _imageManager2Info CImageManager2::GenerateImage(const std::wstring& strInput, NSCommon::smart_ptr<OOX::File> & additionalFile, const std::wstring& oleData, std::wstring strBase64Image) | |
| { | |
| if (IsNeedDownload(strInput)) | |
| return DownloadImage(strInput); | |
| std::map<std::wstring, _imageManager2Info>::const_iterator pPair = m_mapImages.find ((strBase64Image.empty()) ? strInput : strBase64Image); | |
| if (pPair != m_mapImages.end()) | |
| { | |
| smart_ptr<OOX::Media> mediaFile = additionalFile.smart_dynamic_cast<OOX::Media>(); | |
| if (mediaFile.IsInit()) | |
| mediaFile->set_filename(pPair->second.sFilepathAdditional, false); | |
| return pPair->second; | |
| } | |
| std::wstring strExts = _T(".jpg"); | |
| //use GetFileName to avoid defining '.' in the directory as extension | |
| std::wstring strFileName = NSFile::GetFileName(strInput); | |
| int nIndexExt = (int)strFileName.rfind(wchar_t('.')); | |
| if (-1 != nIndexExt) | |
| strExts = strFileName.substr(nIndexExt); | |
| int typeAdditional = 0; | |
| std::wstring strAdditional; | |
| std::wstring strImage = strInput; | |
| int nDisplayType = IsDisplayedImage(strInput); | |
| if (0 != nDisplayType) | |
| { | |
| OOX::CPath oPath = strInput; | |
| std::wstring strFolder = oPath.GetDirectory(); | |
| std::wstring strFileName = oPath.GetFilename(); | |
| strFileName.erase(strFileName.length() - 4, 4); | |
| if(0 != (nDisplayType & 1)) | |
| { | |
| std::wstring strVector = strFolder + strFileName + _T(".wmf"); | |
| if (OOX::CSystemUtility::IsFileExist(strVector)) | |
| { | |
| strImage = strVector; | |
| strExts = _T(".wmf"); | |
| } | |
| } | |
| if(0 != (nDisplayType & 2)) | |
| { | |
| std::wstring strVector = strFolder + strFileName + L".emf"; | |
| if (OOX::CSystemUtility::IsFileExist(strVector)) | |
| { | |
| m_pContentTypes->AddDefault(L"emf"); | |
| strImage = strVector; | |
| strExts = L".emf"; | |
| } | |
| } | |
| if(0 != (nDisplayType & 4)) | |
| { | |
| smart_ptr<OOX::OleObject> oleFile = additionalFile.smart_dynamic_cast<OOX::OleObject>(); | |
| if (oleFile.IsInit()) | |
| { | |
| if (OOX::CSystemUtility::IsFileExist(oleFile->filename()) == false) | |
| { | |
| typeAdditional = 1; | |
| std::wstring strOle = strFolder + strFileName + oleFile->filename().GetExtention(); | |
| if (OOX::CSystemUtility::IsFileExist(strOle)) | |
| { | |
| m_pContentTypes->AddDefault(oleFile->filename().GetExtention(false)); | |
| strAdditional = strOle; | |
| } | |
| else | |
| { | |
| strOle = strFolder + strFileName + L".bin"; | |
| if (OOX::CSystemUtility::IsFileExist(strOle)) | |
| strAdditional = strOle; | |
| } | |
| } | |
| } | |
| } | |
| if(0 != (nDisplayType & 8)) | |
| { | |
| smart_ptr<OOX::Media> mediaFile = additionalFile.smart_dynamic_cast<OOX::Media>(); | |
| if (mediaFile.IsInit()) | |
| { | |
| if (OOX::CSystemUtility::IsFileExist(mediaFile->filename()) == false) | |
| { | |
| typeAdditional = 2; | |
| if (!mediaFile->IsExternal()) | |
| { | |
| std::wstring strMedia = strFolder + strFileName + mediaFile->filename().GetExtention(); | |
| if (OOX::CSystemUtility::IsFileExist(strMedia)) | |
| { | |
| m_pContentTypes->AddDefault(mediaFile->filename().GetExtention(false)); | |
| strAdditional = strMedia; | |
| } | |
| else | |
| { | |
| strMedia = strFolder + strFileName; | |
| if (mediaFile.is<OOX::Audio>()) strMedia += L".wav"; | |
| if (mediaFile.is<OOX::Video>()) strMedia += L".avi"; | |
| if (OOX::CSystemUtility::IsFileExist(strMedia)) | |
| strAdditional = strMedia; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if (!strExts.empty()) | |
| { | |
| m_pContentTypes->AddDefault(strExts.substr(1)); | |
| } | |
| if (oleData.empty() == false) | |
| { | |
| //plugins data - generate ole | |
| typeAdditional = 1; | |
| } | |
| _imageManager2Info oImageManagerInfo = GenerateImageExec(strImage, strExts, strAdditional, typeAdditional, oleData); | |
| if (!oImageManagerInfo.sFilepathAdditional.empty()) | |
| { | |
| smart_ptr<OOX::Media> mediaFile = additionalFile.smart_dynamic_cast<OOX::Media>(); | |
| if (mediaFile.IsInit()) | |
| { | |
| mediaFile->set_filename(oImageManagerInfo.sFilepathAdditional, false); | |
| } | |
| } | |
| if (strBase64Image.empty()) | |
| m_mapImages[strInput] = oImageManagerInfo; | |
| else | |
| m_mapImages [strBase64Image] = oImageManagerInfo; | |
| return oImageManagerInfo; | |
| } | |
| bool CImageManager2::WriteOleData(const std::wstring& sFilePath, const std::wstring& sData) | |
| { | |
| bool bRes = false; | |
| //EncodingMode.unparsed https://github.com/tonyqus/npoi/blob/master/main/POIFS/FileSystem/Ole10Native.cs | |
| POLE::Storage oStorage(sFilePath.c_str()); | |
| if(oStorage.open(true, true)) | |
| { | |
| //CompObj Stream | |
| BYTE dataCompObj[] = {0x01,0x00,0xfe,0xff,0x03,0x0a,0x00,0x00,0xff,0xff,0xff,0xff,0x0c,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x0c,0x00,0x00,0x00,0x4f,0x4c,0x45,0x20,0x50,0x61,0x63,0x6b,0x61,0x67,0x65,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x50,0x61,0x63,0x6b,0x61,0x67,0x65,0x00,0xf4,0x39,0xb2,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; | |
| POLE::Stream oStream1(&oStorage, L"\001CompObj", true, arraysize(dataCompObj)); | |
| oStream1.write(dataCompObj, arraysize(dataCompObj)); | |
| oStream1.flush(); | |
| //ObjInfo Stream | |
| BYTE dataObjInfo[] = {0x00,0x00,0x03,0x00,0x0d,0x00}; | |
| POLE::Stream oStream2(&oStorage, L"\003ObjInfo", true, arraysize(dataObjInfo)); | |
| oStream2.write(dataObjInfo, arraysize(dataObjInfo)); | |
| oStream2.flush(); | |
| //Ole10Native Stream | |
| std::string sDataUtf8 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(sData.c_str(), (LONG)sData.size()); | |
| BYTE head[] = {0x00,0x00,0x00,0x00}; | |
| //LittleEndian | |
| unsigned char* aData = (unsigned char*)sDataUtf8.c_str(); | |
| _UINT32 nDataSize = (_UINT32)sDataUtf8.size(); | |
| memcpy(head, &nDataSize, sizeof(_UINT32)); | |
| POLE::Stream oStream(&oStorage, L"\001Ole10Native", true, arraysize(head) + nDataSize); | |
| oStream.write(head, arraysize(head)); | |
| oStream.write(aData, nDataSize); | |
| oStream.flush(); | |
| oStorage.close(); | |
| bRes = true; | |
| } | |
| return bRes; | |
| } | |
| _imageManager2Info CImageManager2::GenerateMediaExec(const std::wstring& strInput) | |
| { | |
| OOX::CPath oPathOutput; | |
| _imageManager2Info oImageManagerInfo; | |
| std::wstring strExts; | |
| std::wstring strMedia = L"media" + std::to_wstring(++m_lIndexNextImage); | |
| int pos = (int)strInput.rfind(L"."); | |
| if (pos >= 0) | |
| { | |
| strExts = strInput.substr(pos); | |
| m_pContentTypes->AddDefault(strExts.substr(1)); | |
| } | |
| oPathOutput = m_strDstMedia + FILE_SEPARATOR_STR + strMedia + strExts; | |
| if (oPathOutput.GetPath() != strInput && NSFile::CFileBinary::Exists(strInput)) | |
| { | |
| NSFile::CFileBinary::Copy(strInput, oPathOutput.GetPath()); | |
| oImageManagerInfo.sFilepathImage = oPathOutput.GetPath(); | |
| } | |
| return oImageManagerInfo; | |
| } | |
| _imageManager2Info CImageManager2::GenerateImageExec(const std::wstring& strInput, const std::wstring& sExts, const std::wstring& strAdditionalImage, int nAdditionalType, const std::wstring& oleData) | |
| { | |
| OOX::CPath oPathOutput; | |
| _imageManager2Info oImageManagerInfo; | |
| std::wstring strExts = sExts; | |
| std::wstring strImage = L"image" + std::to_wstring(++m_lIndexNextImage); | |
| if ((_T(".jpg") == strExts) || (_T(".jpeg") == strExts) || (_T(".png") == strExts) || (_T(".emf") == strExts) || (_T(".wmf") == strExts)) | |
| { | |
| oPathOutput = m_strDstMedia + FILE_SEPARATOR_STR + strImage + strExts; | |
| if (oPathOutput.GetPath() != strInput && NSFile::CFileBinary::Exists(strInput)) | |
| { | |
| NSFile::CFileBinary::Copy(strInput, oPathOutput.GetPath()); | |
| oImageManagerInfo.sFilepathImage = oPathOutput.GetPath(); | |
| } | |
| } | |
| else | |
| { | |
| // content types!!! | |
| strExts = _T(".png"); | |
| oPathOutput = m_strDstMedia + FILE_SEPARATOR_STR + strImage + strExts; | |
| SaveImageAsPng(strInput, oPathOutput.GetPath()); | |
| oImageManagerInfo.sFilepathImage = oPathOutput.GetPath(); | |
| } | |
| if ((!strAdditionalImage.empty() || !oleData.empty() ) && (nAdditionalType == 1)) | |
| { | |
| std::wstring strAdditionalExt = L".bin"; | |
| int pos = (int)strAdditionalImage.rfind(L"."); | |
| if (pos >= 0) strAdditionalExt = strAdditionalImage.substr(pos); | |
| std::wstring strImageAdditional = L"oleObject" + std::to_wstring(++m_lIndexCounter) + strAdditionalExt; | |
| OOX::CPath pathOutput = m_strDstEmbed + FILE_SEPARATOR_STR + strImageAdditional; | |
| std::wstring strAdditionalImageOut = pathOutput.GetPath(); | |
| if(!oleData.empty()) | |
| { | |
| WriteOleData(strAdditionalImageOut, oleData); | |
| oImageManagerInfo.sFilepathAdditional = strAdditionalImageOut; | |
| } | |
| else if (NSFile::CFileBinary::Exists(strAdditionalImage)) | |
| { | |
| NSFile::CFileBinary::Copy(strAdditionalImage, strAdditionalImageOut); | |
| oImageManagerInfo.sFilepathAdditional = strAdditionalImageOut; | |
| } | |
| } | |
| else if (!strAdditionalImage.empty() && nAdditionalType == 2) | |
| { | |
| std::wstring strAdditionalExt; | |
| int pos = (int)strAdditionalImage.rfind(L"."); | |
| if (pos >= 0) strAdditionalExt = strAdditionalImage.substr(pos); | |
| std::wstring strImageAdditional = L"media" + std::to_wstring(++m_lIndexCounter) + strAdditionalExt; | |
| OOX::CPath pathOutput = m_strDstMedia + FILE_SEPARATOR_STR + strImageAdditional; | |
| std::wstring strAdditionalImageOut = pathOutput.GetPath(); | |
| if (NSFile::CFileBinary::Exists(strAdditionalImage)) | |
| { | |
| NSFile::CFileBinary::Copy(strAdditionalImage, strAdditionalImageOut); | |
| oImageManagerInfo.sFilepathAdditional = strAdditionalImageOut; | |
| } | |
| } | |
| return oImageManagerInfo; | |
| } | |
| void CImageManager2::SaveImageAsPng(const std::wstring& strFileSrc, const std::wstring& strFileDst) | |
| { | |
| CBgraFrame oBgraFrame; | |
| if(oBgraFrame.OpenFile(strFileSrc)) | |
| oBgraFrame.SaveFile(strFileDst, _CXIMAGE_FORMAT_PNG); | |
| } | |
| void CImageManager2::SaveImageAsJPG(const std::wstring& strFileSrc, const std::wstring& strFileDst) | |
| { | |
| CBgraFrame oBgraFrame; | |
| if(oBgraFrame.OpenFile(strFileSrc)) | |
| oBgraFrame.SaveFile(strFileDst, _CXIMAGE_FORMAT_JPG); | |
| } | |
| bool CImageManager2::IsNeedDownload(const std::wstring& strFile) | |
| { | |
| size_t n1 = strFile.find(_T("www")); | |
| size_t n2 = strFile.find(_T("http")); | |
| size_t n3 = strFile.find(_T("ftp")); | |
| size_t n4 = strFile.find(_T("https://")); | |
| //если nI сранивать не с 0, то будут проблемы | |
| //потому что в инсталяции мы кладем файлы в /var/www... | |
| if (0 == n1 || 0 == n2 || 0 == n3 || 0 == n4) | |
| return true; | |
| return false; | |
| } | |
| _imageManager2Info CImageManager2::DownloadImage(const std::wstring& strUrl) | |
| { | |
| std::map<std::wstring, _imageManager2Info>::const_iterator pPair = m_mapImages.find (strUrl); | |
| if (pPair != m_mapImages.end()) | |
| return pPair->second; | |
| std::wstring strExts = _T(".jpg"); | |
| int nIndexExt = (int)strUrl.rfind(wchar_t('.')); | |
| if (-1 != nIndexExt) | |
| strExts = strUrl.substr(nIndexExt); | |
| std::wstring strImage; | |
| int nDisplayType = IsDisplayedImage(strUrl); | |
| if(0 != nDisplayType) | |
| { | |
| std::wstring strInputMetafile = strUrl.substr(0, strUrl.length() - strExts.length()); | |
| std::wstring sDownloadRes; | |
| if(0 != (nDisplayType & 1)) | |
| { | |
| strImage = DownloadImageExec(strInputMetafile + _T(".wmf")); | |
| strExts = _T(".wmf"); | |
| } | |
| else if(0 != (nDisplayType & 2)) | |
| { | |
| strImage = DownloadImageExec(strInputMetafile + _T(".emf")); | |
| strExts = _T(".emf"); | |
| } | |
| else | |
| { | |
| strImage = DownloadImageExec(strUrl); | |
| } | |
| } | |
| else | |
| { | |
| strImage = DownloadImageExec(strUrl); | |
| } | |
| if (!strExts.empty()) | |
| { | |
| m_pContentTypes->AddDefault(strExts.substr(1)); | |
| } | |
| _imageManager2Info oImageManagerInfo; | |
| if (!strImage.empty()) | |
| { | |
| oImageManagerInfo = GenerateImageExec(strImage, strExts, L"", 0, L""); | |
| CDirectory::DeleteFile(strImage); | |
| } | |
| m_mapImages[strUrl] = oImageManagerInfo; | |
| return oImageManagerInfo; | |
| } | |
| std::wstring CImageManager2::DownloadImageExec(const std::wstring& strFile) | |
| { | |
| #ifndef DISABLE_FILE_DOWNLOADER | |
| CFileDownloader oDownloader(strFile, false); | |
| if ( oDownloader.DownloadSync() ) | |
| { | |
| return oDownloader.GetFilePath(); | |
| } | |
| #endif | |
| return _T(""); | |
| } | |
| CBinaryFileWriter::CSeekTableEntry::CSeekTableEntry() | |
| { | |
| Type = 0; | |
| SeekPos = 0; | |
| } | |
| BYTE* CBinaryFileWriter::GetBuffer() | |
| { | |
| return m_pStreamData; | |
| } | |
| _UINT32 CBinaryFileWriter::GetPosition() | |
| { | |
| return m_lPosition; | |
| } | |
| void CBinaryFileWriter::SetPosition(const _UINT32& lPosition) | |
| { | |
| m_lPosition = lPosition; | |
| m_pStreamCur = m_pStreamData + m_lPosition; | |
| } | |
| void CBinaryFileWriter::Skip(const _UINT32& lSize) | |
| { | |
| CheckBufferSize(lSize); | |
| m_lPosition += lSize; | |
| m_pStreamCur = m_pStreamData + m_lPosition; | |
| } | |
| double CBinaryFileWriter::GetShapeHeight() | |
| { | |
| if (m_lCyCurShape == 0) | |
| return -1; | |
| return (double)m_lCyCurShape / 36000; //mm | |
| } | |
| double CBinaryFileWriter::GetShapeWidth() | |
| { | |
| if (m_lCyCurShape == 0) | |
| return -1; | |
| return (double)m_lCxCurShape / 36000; | |
| } | |
| double CBinaryFileWriter::GetShapeY() | |
| { | |
| return (double)m_lYCurShape / 36000; | |
| } | |
| double CBinaryFileWriter::GetShapeX() | |
| { | |
| return (double)m_lXCurShape / 36000; //mm | |
| } | |
| void CBinaryFileWriter::ClearCurShapePositionAndSizes() | |
| { | |
| m_lXCurShape = 0; | |
| m_lYCurShape = 0; | |
| m_lCxCurShape = 0; | |
| m_lCyCurShape = 0; | |
| } | |
| void CBinaryFileWriter::Clear() | |
| { | |
| m_lSize = 0; | |
| m_lPosition = 0; | |
| m_pStreamData = NULL; | |
| m_pStreamCur = NULL; | |
| m_lStackPosition = 0; | |
| memset(m_arStack, 0, MAX_STACK_SIZE * sizeof(_UINT32)); | |
| m_lCxCurShape = 0; | |
| m_lCyCurShape = 0; | |
| m_lXCurShape = 0; | |
| m_lYCurShape = 0; | |
| } | |
| void CBinaryFileWriter::SetMainDocument(BinDocxRW::CDocxSerializer* pMainDoc) | |
| { | |
| m_pMainDocument = pMainDoc; | |
| } | |
| void CBinaryFileWriter::ClearNoAttack() | |
| { | |
| m_lPosition = 0; | |
| m_pStreamCur = m_pStreamData; | |
| m_lStackPosition = 0; | |
| memset(m_arStack, 0, MAX_STACK_SIZE * sizeof(_UINT32)); | |
| } | |
| void CBinaryFileWriter::CheckBufferSize(_UINT32 lPlus) | |
| { | |
| if (NULL != m_pStreamData) | |
| { | |
| size_t nNewSize = m_lPosition + lPlus; | |
| if (nNewSize >= m_lSize) | |
| { | |
| while (nNewSize >= m_lSize) | |
| { | |
| m_lSize *= 2; | |
| } | |
| BYTE* pNew = new BYTE[m_lSize]; | |
| memcpy(pNew, m_pStreamData, m_lPosition); | |
| RELEASEARRAYOBJECTS(m_pStreamData); | |
| m_pStreamData = pNew; | |
| m_pStreamCur = m_pStreamData + m_lPosition; | |
| } | |
| } | |
| else | |
| { | |
| m_lSize = 1024 * 1024; // 1Mb | |
| m_pStreamData = new BYTE[m_lSize]; | |
| m_lPosition = 0; | |
| m_pStreamCur = m_pStreamData; | |
| CheckBufferSize(lPlus); | |
| } | |
| } | |
| void CBinaryFileWriter::WriteBYTE(const BYTE& lValue) | |
| { | |
| CheckBufferSize(BYTE_SIZEOF); | |
| *m_pStreamCur = lValue; | |
| m_lPosition += BYTE_SIZEOF; | |
| m_pStreamCur += BYTE_SIZEOF; | |
| } | |
| void CBinaryFileWriter::WriteSBYTE(const signed char& lValue) | |
| { | |
| CheckBufferSize(BYTE_SIZEOF); | |
| if (lValue < 0) | |
| *m_pStreamCur = (lValue + 256); | |
| else | |
| *m_pStreamCur = lValue; | |
| m_lPosition += BYTE_SIZEOF; | |
| m_pStreamCur += BYTE_SIZEOF; | |
| } | |
| void CBinaryFileWriter::WriteBOOL(const bool& bValue) | |
| { | |
| WriteBYTE((bValue == true) ? 1 : 0); | |
| } | |
| void CBinaryFileWriter::WriteUSHORT(const _UINT16& lValue) | |
| { | |
| CheckBufferSize(UINT16_SIZEOF); | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| memcpy(m_pStreamCur, &lValue, sizeof(_UINT16)); | |
| #else | |
| *((_UINT16*)m_pStreamCur) = lValue; // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPosition += UINT16_SIZEOF; | |
| m_pStreamCur += UINT16_SIZEOF; | |
| } | |
| void CBinaryFileWriter::WriteSHORT(const _INT16& lValue) | |
| { | |
| CheckBufferSize(INT16_SIZEOF); | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| memcpy(m_pStreamCur, &lValue, sizeof(_INT16)); | |
| #else | |
| *((_INT16*)m_pStreamCur) = lValue; // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPosition += INT16_SIZEOF; | |
| m_pStreamCur += INT16_SIZEOF; | |
| } | |
| void CBinaryFileWriter::WriteULONG(const _UINT32& lValue) | |
| { | |
| CheckBufferSize(UINT32_SIZEOF); | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| memcpy(m_pStreamCur, &lValue, sizeof(_UINT32)); | |
| #else | |
| *((_UINT32*)m_pStreamCur) = lValue; // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPosition += UINT32_SIZEOF; | |
| m_pStreamCur += UINT32_SIZEOF; | |
| } | |
| void CBinaryFileWriter::WriteLONG(const _INT32& lValue) | |
| { | |
| CheckBufferSize(INT32_SIZEOF); | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| memcpy(m_pStreamCur, &lValue, sizeof(_INT32)); | |
| #else | |
| *((_INT32*)m_pStreamCur) = lValue; // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPosition += INT32_SIZEOF; | |
| m_pStreamCur += INT32_SIZEOF; | |
| } | |
| void CBinaryFileWriter::WriteLONG64(const _INT64& lValue) | |
| { | |
| CheckBufferSize(INT64_SIZEOF); | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| memcpy(m_pStreamCur, &lValue, sizeof(_INT64)); | |
| #else | |
| *((_INT64*)m_pStreamCur) = lValue; // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPosition += INT64_SIZEOF; | |
| m_pStreamCur += INT64_SIZEOF; | |
| } | |
| void CBinaryFileWriter::WriteINT(const _INT32& lValue) | |
| { | |
| CheckBufferSize(INT32_SIZEOF); | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| memcpy(m_pStreamCur, &lValue, sizeof(_INT32)); | |
| #else | |
| *((_INT32*)m_pStreamCur) = lValue; // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPosition += INT32_SIZEOF; | |
| m_pStreamCur += INT32_SIZEOF; | |
| } | |
| void CBinaryFileWriter::WriteDouble64(const double& dValue) | |
| { | |
| _INT64 _val = (_INT64)(dValue * 100000); | |
| WriteLONG64(_val); | |
| } | |
| void CBinaryFileWriter::WriteDouble(const double& dValue) | |
| { | |
| _INT64 _val = (_INT64)(dValue * 100000); | |
| if (_val > 0x7fffffff) | |
| { | |
| WriteLONG(0x7fffffff); | |
| } | |
| else if ( _val < -0x7fffffff) | |
| { | |
| WriteLONG(-0x7fffffff); | |
| } | |
| else | |
| { | |
| WriteLONG((long)_val); | |
| } | |
| } | |
| void CBinaryFileWriter::WriteDoubleReal(const double& dValue) | |
| { | |
| CheckBufferSize(DOUBLE_SIZEOF); | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| memcpy(m_pStreamCur, &dValue, sizeof(double)); | |
| #else | |
| *((double*)m_pStreamCur) = dValue; // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPosition += DOUBLE_SIZEOF; | |
| m_pStreamCur += DOUBLE_SIZEOF; | |
| } | |
| void CBinaryFileWriter::WriteBYTEArray(const BYTE* pBuffer, size_t len) | |
| { | |
| CheckBufferSize((_UINT32)len); | |
| memcpy(m_pStreamCur, pBuffer, len); | |
| m_lPosition += (_UINT32)len; | |
| m_pStreamCur += len; | |
| } | |
| void CBinaryFileWriter::WriteStringA(std::string& sBuffer) | |
| { | |
| _UINT32 lSize = (_UINT32)sBuffer.length(); | |
| _UINT32 lSizeMem = lSize * sizeof(char); | |
| CheckBufferSize(UINT32_SIZEOF + lSizeMem); | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| memcpy(m_pStreamCur, &lSizeMem, sizeof(_UINT32)); | |
| #else | |
| *((_UINT32*)m_pStreamCur) = lSizeMem; // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPosition += UINT32_SIZEOF; | |
| m_pStreamCur += UINT32_SIZEOF; | |
| memcpy(m_pStreamCur, sBuffer.c_str(), lSizeMem); | |
| m_lPosition += lSizeMem; | |
| m_pStreamCur += lSizeMem; | |
| } | |
| void CBinaryFileWriter::WriteStringW(std::wstring& sBuffer) | |
| { | |
| _WriteStringWithLength(sBuffer.c_str(), (_UINT32)sBuffer.length(), true); | |
| } | |
| void CBinaryFileWriter::WriteStringW(const std::wstring& sBuffer) | |
| { | |
| _WriteStringWithLength(sBuffer.c_str(), (_UINT32)sBuffer.length(), true); | |
| } | |
| void CBinaryFileWriter::WriteStringW2(std::wstring& sBuffer) | |
| { | |
| _WriteStringWithLength(sBuffer.c_str(), (_UINT32)sBuffer.length(), false); | |
| } | |
| void CBinaryFileWriter::WriteStringW3(std::wstring& sBuffer) | |
| { | |
| _WriteString(sBuffer.c_str(), (_UINT32)sBuffer.length()); | |
| } | |
| void CBinaryFileWriter::WriteStringW3(const std::wstring& sBuffer) | |
| { | |
| _WriteString(sBuffer.c_str(), (_UINT32)sBuffer.length()); | |
| } | |
| void CBinaryFileWriter::WriteStringW4(const std::wstring& sBuffer) | |
| { | |
| _WriteString(sBuffer.c_str(), (_UINT32)sBuffer.length()); | |
| } | |
| void CBinaryFileWriter::WriteStringUtf8(const std::wstring& sBuffer) | |
| { | |
| BYTE* pData = NULL; | |
| LONG lLen = 0; | |
| NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sBuffer.c_str(), (LONG)sBuffer.length(), pData, lLen, false); | |
| WriteBYTEArray(pData, lLen); | |
| RELEASEARRAYOBJECTS(pData); | |
| } | |
| CBinaryFileWriter::CBinaryFileWriter() | |
| { | |
| m_pMainDocument = NULL; | |
| m_pCommon = new CCommonWriter(); | |
| //m_pCommonRels = new NSCommon::smart_ptr<PPTX::CCommonRels>(); | |
| m_pCurrentContainer = new NSCommon::smart_ptr<OOX::IFileContainer>(); | |
| m_pTheme = new NSCommon::smart_ptr<PPTX::Theme>(); | |
| m_pClrMap = new NSCommon::smart_ptr<PPTX::Logic::ClrMap>(); | |
| Clear(); | |
| } | |
| CBinaryFileWriter::~CBinaryFileWriter() | |
| { | |
| RELEASEARRAYOBJECTS (m_pStreamData); | |
| RELEASEOBJECT (m_pCommon); | |
| //RELEASEOBJECT (m_pCommonRels); | |
| RELEASEOBJECT (m_pCurrentContainer); | |
| RELEASEOBJECT (m_pTheme); | |
| RELEASEOBJECT (m_pClrMap); | |
| } | |
| void CBinaryFileWriter::StartRecord(_INT32 lType) | |
| { | |
| m_arStack[m_lStackPosition] = m_lPosition + 5; // sizeof(BYTE) + sizeof(_UINT32) | |
| m_lStackPosition++; | |
| WriteBYTE((BYTE)lType); | |
| WriteULONG(0); | |
| } | |
| void CBinaryFileWriter::EndRecord() | |
| { | |
| m_lStackPosition--; | |
| _UINT32 size_record = m_lPosition - m_arStack[m_lStackPosition]; | |
| (*(_UINT32*)(m_pStreamData + m_arStack[m_lStackPosition] - 4)) = size_record ; | |
| } | |
| void CBinaryFileWriter::StartMainRecord(_INT32 lType) | |
| { | |
| CSeekTableEntry oEntry; | |
| oEntry.Type = lType; | |
| oEntry.SeekPos = m_lPosition; | |
| m_arMainTables.push_back(oEntry); | |
| //StartRecord(lType); | |
| } | |
| void CBinaryFileWriter::WriteReserved(size_t lCount) | |
| { | |
| CheckBufferSize((_UINT32)lCount); | |
| memset(m_pStreamCur, 0, lCount); | |
| m_pStreamCur += lCount; | |
| m_lPosition += (_UINT32)lCount; | |
| } | |
| void CBinaryFileWriter::WriteMainPart(_UINT32 nStartPos) | |
| { | |
| BYTE* pData = m_pStreamData + nStartPos; | |
| size_t nCount = m_arMainTables.size(); | |
| for (size_t i = 0; i < nCount; i++) | |
| { | |
| *pData = (BYTE)m_arMainTables[i].Type; | |
| ++pData; | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| memcpy(pData, &m_arMainTables[i].SeekPos, sizeof(_INT32)); | |
| #else | |
| *((_INT32*)pData) = m_arMainTables[i].SeekPos; // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| pData += 4; | |
| } | |
| } | |
| void CBinaryFileWriter::WriteString1(int type, const std::wstring& val) | |
| { | |
| BYTE bType = (BYTE)type; | |
| WriteBYTE(bType); | |
| std::wstring* s = const_cast<std::wstring*>(&val); | |
| _WriteStringWithLength(s->c_str(), (_UINT32)s->length(), false); | |
| } | |
| void CBinaryFileWriter::WriteString2(int type, const NSCommon::nullable_string& val) | |
| { | |
| if (val.is_init()) | |
| WriteString1(type, *val); | |
| } | |
| void CBinaryFileWriter::WriteString(const std::wstring& val) | |
| { | |
| std::wstring* s = const_cast<std::wstring*>(&val); | |
| _WriteStringWithLength(s->c_str(), (_UINT32)s->length(), false); | |
| } | |
| void CBinaryFileWriter::WriteStringData(const WCHAR* pData, _UINT32 len) | |
| { | |
| _WriteStringWithLength(pData, len, false); | |
| } | |
| void CBinaryFileWriter::WriteString1Data(int type, const WCHAR* pData, _UINT32 len) | |
| { | |
| BYTE bType = (BYTE)type; | |
| WriteBYTE(bType); | |
| _WriteStringWithLength(pData, len, false); | |
| } | |
| void CBinaryFileWriter::WriteBool1(int type, const bool& val) | |
| { | |
| BYTE bType = (BYTE)type; | |
| WriteBYTE(bType); | |
| WriteBYTE((val == true) ? 1 : 0); | |
| } | |
| void CBinaryFileWriter::WriteBool2(int type, const NSCommon::nullable_bool& val) | |
| { | |
| if (val.is_init()) | |
| WriteBool1(type, *val); | |
| } | |
| void CBinaryFileWriter::WriteInt1(int type, const int& val) | |
| { | |
| BYTE bType = (BYTE)type; | |
| WriteBYTE(bType); | |
| WriteINT(val); | |
| } | |
| void CBinaryFileWriter::WriteInt2(int type, const NSCommon::nullable_int& val) | |
| { | |
| if (val.is_init()) | |
| WriteInt1(type, *val); | |
| } | |
| void CBinaryFileWriter::WriteDouble1(int type, const double& val) | |
| { | |
| int _val = (int)(val * 10000); | |
| WriteInt1(type, _val); | |
| } | |
| void CBinaryFileWriter::WriteDouble2(int type, const NSCommon::nullable_double& val) | |
| { | |
| if (val.is_init()) | |
| WriteDouble1(type, *val); | |
| } | |
| void CBinaryFileWriter::WriteSize_t1(int type, const size_t& val) | |
| { | |
| BYTE bType = (BYTE)type; | |
| WriteBYTE(bType); | |
| _UINT32 ival = (_UINT32)val; | |
| WriteULONG(ival); | |
| } | |
| void CBinaryFileWriter::WriteSize_t2(int type, const NSCommon::nullable_sizet& val) | |
| { | |
| if (val.is_init()) | |
| WriteSize_t1(type, *val); | |
| } | |
| void CBinaryFileWriter::GetBase64File(const std::wstring& sFile, std::string& strDst64) | |
| { | |
| CFile oFile; | |
| HRESULT hr = oFile.OpenFile(sFile); | |
| if (S_OK != hr) | |
| { | |
| strDst64 = ""; | |
| return; | |
| } | |
| DWORD dwLen = (DWORD)oFile.GetFileSize(); | |
| BYTE* pBuffer = new BYTE[dwLen]; | |
| oFile.SetPosition(0); | |
| oFile.ReadFile(pBuffer, dwLen); | |
| int nBase64BufferLen = Base64::Base64EncodeGetRequiredLength((int)dwLen, Base64::B64_BASE64_FLAG_NOCRLF); | |
| BYTE *pbBase64Buffer = new BYTE[nBase64BufferLen + 1 + 64]; | |
| pbBase64Buffer[nBase64BufferLen] = '\0'; | |
| //if (true == Base64::Base64Encode(pBuffer, (int)dwLen, pbBase64Buffer, &nBase64BufferLen, Base64::B64_BASE64_FLAG_NOCRLF)) | |
| if (true == Base64_1::Base64Encode(pBuffer, (int)dwLen, pbBase64Buffer, &nBase64BufferLen)) | |
| { | |
| //strDst64.SetString(pbBase64Buffer, nBase64BufferLen); | |
| strDst64 = (char*)pbBase64Buffer; | |
| } | |
| RELEASEARRAYOBJECTS(pbBase64Buffer); | |
| RELEASEARRAYOBJECTS(pBuffer); | |
| oFile.CloseFile(); | |
| //DeleteFile(sFile); | |
| } | |
| void CBinaryFileWriter::WriteTheme64(_INT32 lIndex, const std::wstring& sFile) | |
| { | |
| GetBase64File(sFile, m_pCommon->m_oRels[lIndex].m_strImageBase64); | |
| } | |
| void CBinaryFileWriter::WriteLayoutTheme64(_INT32 lIndexTheme, _INT32 lIndexLayout, const std::wstring& sFile) | |
| { | |
| GetBase64File(sFile, m_pCommon->m_oRels[lIndexTheme].m_arLayoutImagesBase64[lIndexLayout]); | |
| } | |
| std::wstring CBinaryFileWriter::GetFolderForGenerateImages() | |
| { | |
| return m_strMainFolder + _T("\\extract_themes"); | |
| } | |
| // embedded fonts | |
| void CBinaryFileWriter::WriteEmbeddedFonts() | |
| { | |
| if (NULL == m_pCommon->m_pNativePicker) | |
| return; | |
| if (!m_pCommon->m_pNativePicker->m_bIsEmbeddedFonts) | |
| return; | |
| StartMainRecord(NSBinPptxRW::NSMainTables::FontsEmbedded); | |
| // добавим мега шрифт | |
| m_pCommon->m_pNativePicker->m_oEmbeddedFonts.CheckString(_T(".)abcdefghijklmnopqrstuvwxyz")); | |
| m_pCommon->m_pNativePicker->m_oEmbeddedFonts.CheckFont(_T("Wingdings 3"), m_pCommon->m_pNativePicker->m_pFontManager); | |
| m_pCommon->m_pNativePicker->m_oEmbeddedFonts.CheckFont(_T("Arial"), m_pCommon->m_pNativePicker->m_pFontManager); | |
| StartRecord(NSBinPptxRW::NSMainTables::FontsEmbedded); | |
| m_pCommon->m_pNativePicker->m_oEmbeddedFonts.WriteEmbeddedFonts(this); | |
| EndRecord(); | |
| } | |
| bool CBinaryFileWriter::GetSafearray(BYTE **ppArray, size_t& szCount) | |
| { | |
| if (NULL == ppArray) | |
| return false; | |
| _UINT32 lBinarySize = this->GetPosition(); | |
| if (0 == lBinarySize) | |
| return false; | |
| *ppArray = new BYTE [lBinarySize]; | |
| szCount = lBinarySize; | |
| memcpy(*ppArray, this->GetBuffer(), lBinarySize); | |
| return true; | |
| } | |
| _INT32 CBinaryFileWriter::_WriteString(const WCHAR* sBuffer, _UINT32 lCount) | |
| { | |
| _INT32 lSizeMem = 0; | |
| if (sizeof(wchar_t) == 4) | |
| { | |
| _INT32 lSizeMemMax = 4 * lCount + 2;//2 - for null terminator | |
| CheckBufferSize(lSizeMemMax); | |
| NSFile::CUtf8Converter::GetUtf16StringFromUnicode_4bytes(sBuffer, lCount, m_pStreamCur, lSizeMem); | |
| } | |
| else | |
| { | |
| lSizeMem = 2 * lCount; | |
| CheckBufferSize(lSizeMem); | |
| memcpy(m_pStreamCur, sBuffer, lSizeMem); | |
| } | |
| m_lPosition += lSizeMem; | |
| m_pStreamCur += lSizeMem; | |
| return lSizeMem; | |
| } | |
| void CBinaryFileWriter::_WriteStringWithLength(const WCHAR* sBuffer, _UINT32 lCount, bool bByte) | |
| { | |
| if (sizeof(wchar_t) == 4) | |
| { | |
| _INT32 lSizeMemMax = 4 * lCount + 2;//2 - for null terminator | |
| CheckBufferSize(UINT32_SIZEOF + lSizeMemMax); | |
| } | |
| else | |
| { | |
| _INT32 lSizeMem = 2 * lCount; | |
| CheckBufferSize(UINT32_SIZEOF + lSizeMem); | |
| } | |
| //skip size | |
| m_lPosition += UINT32_SIZEOF; | |
| m_pStreamCur += UINT32_SIZEOF; | |
| //write string | |
| _INT32 lSizeMem = _WriteString(sBuffer, lCount); | |
| //back to size | |
| m_lPosition -= lSizeMem; | |
| m_pStreamCur -= lSizeMem; | |
| m_lPosition -= UINT32_SIZEOF; | |
| m_pStreamCur -= UINT32_SIZEOF; | |
| //write size | |
| if (bByte) | |
| { | |
| //byte | |
| WriteLONG(lSizeMem); | |
| } | |
| else | |
| { | |
| //length | |
| WriteLONG(lSizeMem / 2); | |
| } | |
| //skip string | |
| m_lPosition += lSizeMem; | |
| m_pStreamCur += lSizeMem; | |
| } | |
| CStreamBinaryWriter::CStreamBinaryWriter(size_t bufferSize) | |
| { | |
| m_lSize = bufferSize; | |
| m_pStreamData = new BYTE[bufferSize]; | |
| m_lPosition = 0; | |
| m_pStreamCur = m_pStreamData; | |
| m_lPositionFlushed = 0; | |
| } | |
| void CStreamBinaryWriter::CheckBufferSize(_UINT32 lPlus) | |
| { | |
| if ((m_lPosition + lPlus) > m_lSize) | |
| { | |
| Flush(); | |
| if ((m_lPosition + lPlus) > m_lSize) | |
| { | |
| CBinaryFileWriter::CheckBufferSize(lPlus); | |
| } | |
| } | |
| } | |
| _UINT32 CStreamBinaryWriter::GetPositionAbsolute() | |
| { | |
| return m_lPosition + m_lPositionFlushed; | |
| } | |
| void CStreamBinaryWriter::CloseFile() | |
| { | |
| Flush(); | |
| CFileBinary::CloseFile(); | |
| } | |
| void CStreamBinaryWriter::Flush() | |
| { | |
| if (m_lPosition > 0) | |
| { | |
| CFileBinary::WriteFile(m_pStreamData, m_lPosition); | |
| } | |
| m_lPositionFlushed += m_lPosition; | |
| m_lPosition = 0; | |
| m_pStreamCur = m_pStreamData; | |
| } | |
| CXlsbBinaryWriter::CXlsbBinaryWriter(size_t bufferSize) : CStreamBinaryWriter(bufferSize) | |
| { | |
| } | |
| void CXlsbBinaryWriter::XlsbStartRecord(_INT16 lType, _INT32 nLen) | |
| { | |
| //Type | |
| if (lType < 0x80) | |
| { | |
| WriteBYTE(lType); | |
| } | |
| else | |
| { | |
| WriteBYTE((lType & 0x7F) | 0x80); | |
| WriteBYTE(lType >> 7); | |
| } | |
| //Len | |
| for (int i = 0; i < 4; ++i) | |
| { | |
| BYTE nPart = nLen & 0x7F; | |
| nLen = nLen >> 7; | |
| if(nLen == 0) | |
| { | |
| WriteBYTE(nPart); | |
| break; | |
| } | |
| else | |
| { | |
| WriteBYTE(nPart | 0x80); | |
| } | |
| } | |
| } | |
| void CXlsbBinaryWriter::XlsbEndRecord() | |
| { | |
| } | |
| CRelsGenerator::CRelsGenerator(CImageManager2* pManager) : m_lNextRelsID(1), m_mapImages() | |
| { | |
| m_pManager = pManager; | |
| m_pWriter = new NSStringUtils::CStringBuilder(); | |
| } | |
| CRelsGenerator::~CRelsGenerator() | |
| { | |
| RELEASEOBJECT(m_pWriter); | |
| } | |
| void CRelsGenerator::Clear() | |
| { | |
| m_pWriter->ClearNoAttack(); | |
| m_lNextRelsID = 1; | |
| m_mapImages.clear(); | |
| m_mapLinks.clear(); | |
| } | |
| void CRelsGenerator::StartRels() | |
| { | |
| m_pWriter->WriteString(_T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>")); | |
| m_pWriter->WriteString(_T("<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">")); | |
| } | |
| void CRelsGenerator::StartTheme() | |
| { | |
| m_pWriter->WriteString(_T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>")); | |
| m_pWriter->WriteString(_T("<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">")); | |
| } | |
| void CRelsGenerator::StartMaster(int nIndexTheme, const _slideMasterInfo& oInfo) | |
| { | |
| m_pWriter->WriteString(_T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>")); | |
| m_pWriter->WriteString(_T("<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">")); | |
| int nCountLayouts = (int)oInfo.m_arLayouts.size(); | |
| for (int i = 0; i < nCountLayouts; ++i) | |
| { | |
| std::wstring str = L"<Relationship Id=\"rId" + | |
| std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout\" Target=\"../slideLayouts/slideLayout" + | |
| std::to_wstring(oInfo.m_arLayouts[i] + 1) + | |
| L".xml\"/>"; | |
| m_pWriter->WriteString(str); | |
| } | |
| std::wstring s = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"../theme/theme" + | |
| std::to_wstring(nIndexTheme + 1) + L".xml\"/>"; | |
| m_pWriter->WriteString(s); | |
| } | |
| void CRelsGenerator::StartThemeNotesMaster(int nIndexTheme) | |
| { | |
| m_pWriter->WriteString(_T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>")); | |
| m_pWriter->WriteString(_T("<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">")); | |
| std::wstring s = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"../theme/theme" + | |
| std::to_wstring(nIndexTheme + 1) + L".xml\"/>"; | |
| m_pWriter->WriteString(s); | |
| } | |
| void CRelsGenerator::StartLayout(int nIndexTheme) | |
| { | |
| m_pWriter->WriteString(_T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>")); | |
| m_pWriter->WriteString(_T("<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">")); | |
| std::wstring str = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster\" Target=\"../slideMasters/slideMaster" + | |
| std::to_wstring(nIndexTheme + 1) + L".xml\"/>"; | |
| m_pWriter->WriteString(str); | |
| } | |
| void CRelsGenerator::StartSlide(int nIndexSlide, int nIndexLayout, int nIndexNotes) | |
| { | |
| m_pWriter->WriteString(_T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>")); | |
| m_pWriter->WriteString(_T("<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">")); | |
| std::wstring str = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout\" Target=\"../slideLayouts/slideLayout" + | |
| std::to_wstring(nIndexLayout + 1) + L".xml\"/>"; | |
| m_pWriter->WriteString(str); | |
| if (nIndexNotes >= 0) | |
| { | |
| str = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide\" Target=\"../notesSlides/notesSlide" + | |
| std::to_wstring(nIndexNotes + 1) + L".xml\"/>"; | |
| m_pWriter->WriteString(str); | |
| } | |
| } | |
| void CRelsGenerator::StartNotes(int nIndexSlide) | |
| { | |
| m_pWriter->WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>"); | |
| m_pWriter->WriteString(L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">"); | |
| std::wstring sNum = std::to_wstring(nIndexSlide + 1); | |
| std::wstring strNoteSlideRels = L"<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide\" Target=\"../slides/slide" + sNum + L".xml\"/>"; | |
| m_pWriter->WriteString(strNoteSlideRels); | |
| m_pWriter->WriteString(L"<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster\" Target=\"../notesMasters/notesMaster1.xml\"/>"); | |
| m_lNextRelsID = 3; | |
| } | |
| void CRelsGenerator::WriteMasters(int nCount) | |
| { | |
| for (int i = 0; i < nCount; ++i) | |
| { | |
| std::wstring strRels = L"<Relationship Id=\"rId" + std::to_wstring( m_lNextRelsID++ ) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster\" Target=\"slideMasters/slideMaster" + | |
| std::to_wstring(i + 1) + L".xml\"/>"; | |
| m_pWriter->WriteString(strRels); | |
| } | |
| } | |
| void CRelsGenerator::WriteThemes(int nCount) | |
| { | |
| for (int i = 0; i < nCount; ++i) | |
| { | |
| std::wstring strRels = L"<Relationship Id=\"rId" + std::to_wstring( m_lNextRelsID++ ) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"theme/theme" + | |
| std::to_wstring(i + 1) + L".xml\"/>"; | |
| m_pWriter->WriteString(strRels); | |
| } | |
| } | |
| void CRelsGenerator::WriteSlides(int nCount) | |
| { | |
| for (int i = 0; i < nCount; ++i) | |
| { | |
| std::wstring strRels = L"<Relationship Id=\"rId" + std::to_wstring( m_lNextRelsID++ ) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide\" Target=\"slides/slide" + | |
| std::to_wstring(i + 1) + L".xml\"/>"; | |
| m_pWriter->WriteString(strRels); | |
| } | |
| } | |
| void CRelsGenerator::WriteSlideComments(int nComment) | |
| { | |
| std::wstring strRels = L"<Relationship Id=\"rId" + std::to_wstring( m_lNextRelsID++ ) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments\" Target=\"../comments/comment" + | |
| std::to_wstring(nComment) + L".xml\"/>"; | |
| m_pWriter->WriteString(strRels); | |
| } | |
| void CRelsGenerator::WriteNotesMaster() | |
| { | |
| std::wstring strRels0 = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster\" Target=\"notesMasters/notesMaster1.xml\"/>"; | |
| m_pWriter->WriteString(strRels0); | |
| } | |
| void CRelsGenerator::WritePresentationComments(int nComment) | |
| { | |
| std::wstring strRels = L"<Relationship Id=\"rId" + std::to_wstring( m_lNextRelsID++ ) + | |
| L"\" Type=\"http://schemas.onlyoffice.com/comments\" Target=\"comments/comment" + | |
| std::to_wstring(nComment) + L".xml\"/>"; | |
| m_pWriter->WriteString(strRels); | |
| } | |
| void CRelsGenerator::EndPresentationRels(bool bIsCommentsAuthors, bool bIsVbaProject, bool bIsJsaProject) | |
| { | |
| std::wstring strRels1 = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps\" Target=\"presProps.xml\" />"; | |
| std::wstring strRels2 = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles\" Target=\"tableStyles.xml\" />"; | |
| std::wstring strRels3 = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps\" Target=\"viewProps.xml\" />"; | |
| m_pWriter->WriteString(strRels1); | |
| m_pWriter->WriteString(strRels2); | |
| m_pWriter->WriteString(strRels3); | |
| if (bIsCommentsAuthors) | |
| { | |
| std::wstring strRels4 = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors\" Target=\"commentAuthors.xml\"/>"; | |
| m_pWriter->WriteString(strRels4); | |
| } | |
| if (bIsVbaProject) | |
| { | |
| std::wstring strRels4 = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"http://schemas.microsoft.com/office/2006/relationships/vbaProject\" Target=\"vbaProject.bin\"/>"; | |
| m_pWriter->WriteString(strRels4); | |
| } | |
| if (bIsJsaProject) | |
| { | |
| std::wstring strRels5 = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) + | |
| L"\" Type=\"" + OOX::FileTypes::JsaProject.RelationType() + L"\" Target=\"" + OOX::FileTypes::JsaProject.DefaultFileName().GetPath() + L"\"/>"; | |
| m_pWriter->WriteString(strRels5); | |
| } | |
| } | |
| void CRelsGenerator::CloseRels() | |
| { | |
| m_pWriter->WriteString(_T("</Relationships>")); | |
| } | |
| void CRelsGenerator::AddRels(const std::wstring& strRels) | |
| { | |
| m_pWriter->WriteString(strRels); | |
| } | |
| void CRelsGenerator::SaveRels(const std::wstring& strFile) | |
| { | |
| CFile oFile; | |
| oFile.CreateFile(strFile); | |
| std::wstring strMem = m_pWriter->GetData(); | |
| oFile.WriteStringUTF8(strMem); | |
| oFile.CloseFile(); | |
| } | |
| _relsGeneratorInfo CRelsGenerator::WriteMedia(const std::wstring& strImage, int type) | |
| { | |
| _imageManager2Info oImageManagerInfo = m_pManager->GenerateMedia(strImage); | |
| std::wstring strImageRelsPath; | |
| if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strImageRelsPath = L"media/"; | |
| else strImageRelsPath = L"../media/"; | |
| _relsGeneratorInfo oRelsGeneratorInfo; | |
| if (!oImageManagerInfo.sFilepathImage.empty()) | |
| { | |
| strImageRelsPath += OOX::CPath(oImageManagerInfo.sFilepathImage).GetFilename(); | |
| std::map<std::wstring, _relsGeneratorInfo>::iterator pPair = m_mapImages.find(strImageRelsPath); | |
| if (m_mapImages.end() != pPair) | |
| { | |
| return pPair->second; | |
| } | |
| oRelsGeneratorInfo.nImageRId = m_lNextRelsID++; | |
| oRelsGeneratorInfo.sFilepathImage = oImageManagerInfo.sFilepathImage; | |
| std::wstring strRid = L"rId" + std::to_wstring(oRelsGeneratorInfo.nImageRId); | |
| if (type == 0) | |
| { | |
| m_pWriter->WriteString( L"<Relationship Id=\"" + strRid + | |
| L"\" Type=\"http://schemas.microsoft.com/office/2007/relationships/media\" Target=\"" + strImageRelsPath + | |
| L"\"/>"); | |
| } | |
| else if (type == 1) | |
| { | |
| m_pWriter->WriteString( L"<Relationship Id=\"" + strRid + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio\" Target=\"" + strImageRelsPath + | |
| L"\"/>"); | |
| } | |
| } | |
| m_mapImages.insert(std::pair<std::wstring, _relsGeneratorInfo>(strImageRelsPath, oRelsGeneratorInfo)); | |
| return oRelsGeneratorInfo; | |
| } | |
| _relsGeneratorInfo CRelsGenerator::WriteImage(const std::wstring& strImage, smart_ptr<OOX::File> & additionalFile, const std::wstring& oleData, std::wstring strBase64Image = _T("")) | |
| { | |
| _imageManager2Info oImageManagerInfo = m_pManager->GenerateImage(strImage, additionalFile, oleData, strBase64Image); | |
| std::wstring strImageRelsPath; | |
| if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strImageRelsPath = L"media/"; | |
| else strImageRelsPath = L"../media/"; | |
| _relsGeneratorInfo oRelsGeneratorInfo; | |
| if (!oImageManagerInfo.sFilepathImage.empty()) | |
| { | |
| strImageRelsPath += OOX::CPath(oImageManagerInfo.sFilepathImage).GetFilename(); | |
| std::map<std::wstring, _relsGeneratorInfo>::iterator pPair = m_mapImages.find(strImageRelsPath); | |
| if (m_mapImages.end() != pPair) | |
| { | |
| return pPair->second; | |
| } | |
| oRelsGeneratorInfo.nImageRId = m_lNextRelsID++; | |
| oRelsGeneratorInfo.sFilepathImage = oImageManagerInfo.sFilepathImage; | |
| std::wstring strRid = L"rId" + std::to_wstring(oRelsGeneratorInfo.nImageRId); | |
| m_pWriter->WriteString( L"<Relationship Id=\"" + strRid + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"" + strImageRelsPath + | |
| L"\"/>"); | |
| } | |
| if(additionalFile.is<OOX::OleObject>()) | |
| { | |
| smart_ptr<OOX::OleObject> oleFile = additionalFile.smart_dynamic_cast<OOX::OleObject>(); | |
| std::wstring strOleRelsPath; | |
| oRelsGeneratorInfo.nOleRId = m_lNextRelsID++; | |
| oRelsGeneratorInfo.sFilepathOle = oleFile->filename().GetPath(); | |
| if (m_pManager->m_nDocumentType != XMLWRITER_DOC_TYPE_XLSX) | |
| { | |
| std::wstring strRid = L"rId" + std::to_wstring(oRelsGeneratorInfo.nOleRId); | |
| if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strOleRelsPath = L"embeddings/"; | |
| else strOleRelsPath = L"../embeddings/"; | |
| strOleRelsPath += oleFile->filename().GetFilename(); | |
| if (oleFile->isMsPackage()) | |
| { | |
| m_pWriter->WriteString( L"<Relationship Id=\"" + strRid | |
| + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/package\" Target=\"" + | |
| strOleRelsPath + L"\"/>"); | |
| }else{ | |
| m_pWriter->WriteString( L"<Relationship Id=\"" + strRid | |
| + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject\" Target=\"" + | |
| strOleRelsPath + L"\"/>"); | |
| } | |
| } | |
| } | |
| else if(additionalFile.is<OOX::Media>()) | |
| { | |
| smart_ptr<OOX::Media> mediaFile = additionalFile.smart_dynamic_cast<OOX::Media>(); | |
| std::wstring strMediaRelsPath; | |
| oRelsGeneratorInfo.nMediaRId = m_lNextRelsID++; | |
| oRelsGeneratorInfo.sFilepathOle = mediaFile->filename().GetPath(); | |
| if (m_pManager->m_nDocumentType != XMLWRITER_DOC_TYPE_XLSX) | |
| { | |
| std::wstring strRid = L"rId" + std::to_wstring(oRelsGeneratorInfo.nMediaRId); | |
| if (mediaFile->IsExternal()) | |
| { | |
| strMediaRelsPath = mediaFile->filename().GetFilename(); | |
| } | |
| else | |
| { | |
| if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strMediaRelsPath = L"media/"; | |
| else strMediaRelsPath = L"../media/"; | |
| strMediaRelsPath += mediaFile->filename().GetFilename(); | |
| m_pWriter->WriteString( L"<Relationship Id=\"" + strRid | |
| + L"\" Type=\"http://schemas.microsoft.com/office/2007/relationships/media\" Target=\"" + | |
| strMediaRelsPath + L"\"" + (mediaFile->IsExternal() ? L" TargetMode=\"External\"" : L"") + L"/>"); | |
| } | |
| } | |
| } | |
| m_mapImages.insert(std::pair<std::wstring, _relsGeneratorInfo>(strImageRelsPath, oRelsGeneratorInfo)); | |
| return oRelsGeneratorInfo; | |
| } | |
| unsigned int CRelsGenerator::WriteChart(int nChartNumber, _INT32 lDocType = XMLWRITER_DOC_TYPE_PPTX) | |
| { | |
| std::wstring strChart = L"charts/chart" + std::to_wstring(nChartNumber) + L".xml"; | |
| if (lDocType != XMLWRITER_DOC_TYPE_DOCX) | |
| { | |
| strChart = L"../" + strChart; | |
| } | |
| std::wstring strRid = L"rId" + std::to_wstring(m_lNextRelsID++); | |
| std::wstring strRels = L"<Relationship Id=\"" + strRid + | |
| L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart\" Target=\"" + | |
| strChart + L"\"/>"; | |
| m_pWriter->WriteString(strRels); | |
| return m_lNextRelsID - 1; | |
| } | |
| unsigned int CRelsGenerator::WriteRels(const std::wstring& bsType, const std::wstring& bsTarget, const std::wstring& bsTargetMode) | |
| { | |
| std::wstring strRid = L"rId" + std::to_wstring(m_lNextRelsID++); | |
| std::wstring strType = _T("Type=\"") + bsType + _T("\" "); | |
| std::wstring strTarget = _T("Target=\"") + bsTarget + _T("\" "); | |
| std::wstring strTargetMode = bsTargetMode.empty() ? _T("") : (_T("TargetMode=\"") + bsTargetMode + _T("\"")); | |
| std::wstring strRels = _T("<Relationship Id=\"") + strRid + _T("\" ") + strType + strTarget + strTargetMode + _T("/>"); | |
| m_pWriter->WriteString(strRels); | |
| return m_lNextRelsID - 1; | |
| } | |
| unsigned int CRelsGenerator::WriteHyperlink(const std::wstring& strLink, const bool& bIsActionInit) | |
| { | |
| std::map<std::wstring, unsigned int>::iterator pPair = m_mapLinks.find(strLink); | |
| if (m_mapLinks.end() != pPair) | |
| { | |
| return pPair->second; | |
| } | |
| m_mapLinks.insert(std::pair<std::wstring, unsigned int>(strLink, m_lNextRelsID)); | |
| std::wstring strRid = L"rId" + std::to_wstring(m_lNextRelsID++); | |
| std::wstring sLink = XmlUtils::EncodeXmlString(strLink); | |
| bool bIsSlide = (0 == sLink.find(_T("slide"))); | |
| if (!bIsActionInit) | |
| bIsSlide = false; | |
| std::wstring strRels; | |
| if (!bIsSlide) | |
| { | |
| strRels = L"<Relationship Id=\"" + strRid | |
| + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\" Target=\"" + sLink | |
| + L"\" TargetMode=\"External\"/>"; | |
| } | |
| else | |
| { | |
| strRels = L"<Relationship Id=\"" + strRid | |
| + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide\" Target=\"" + sLink | |
| + L"\"/>"; | |
| } | |
| m_pWriter->WriteString(strRels); | |
| return m_lNextRelsID - 1; | |
| } | |
| CBinaryFileReader::CBinaryFileReader() | |
| { | |
| m_pMainDocument = NULL; | |
| m_lNextId = 0; | |
| m_lChartNumber = 1; | |
| m_nDocumentType = XMLWRITER_DOC_TYPE_PPTX; | |
| m_pRels = new CRelsGenerator(); | |
| m_nCurrentRelsStack = -1; | |
| } | |
| CBinaryFileReader::~CBinaryFileReader() | |
| { | |
| RELEASEOBJECT(m_pRels); | |
| size_t nCountStackRels = m_stackRels.size(); | |
| for (size_t i = 0; i < nCountStackRels; ++i) | |
| { | |
| CRelsGenerator* pCur = m_stackRels[i]; | |
| RELEASEOBJECT(pCur); | |
| } | |
| m_stackRels.clear(); | |
| } | |
| void CBinaryFileReader::SetMainDocument(BinDocxRW::CDocxSerializer* pMainDoc) | |
| { | |
| m_pMainDocument = pMainDoc; | |
| } | |
| void CBinaryFileReader::Init(BYTE* pData, _INT32 lStart, _INT32 lSize) | |
| { | |
| m_pData = pData; | |
| m_lSize = lSize + lStart; | |
| m_lPos = lStart; | |
| m_pDataCur = m_pData + m_lPos; | |
| } | |
| _INT32 CBinaryFileReader::GenerateNextId() | |
| { | |
| ++m_lNextId; | |
| return m_lNextId; | |
| } | |
| int CBinaryFileReader::Seek(LONG _pos) | |
| { | |
| if (_pos > m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| m_lPos = _pos; | |
| m_pDataCur = m_pData + m_lPos; | |
| return 0; | |
| } | |
| int CBinaryFileReader::Skip(LONG _skip) | |
| { | |
| if (_skip < 0) | |
| return 1; | |
| return Seek(m_lPos + _skip); | |
| } | |
| bool CBinaryFileReader::Peek(LONG nSizeToRead = 0) | |
| { | |
| return !(m_lPos + nSizeToRead > m_lSize); | |
| } | |
| // 1 bytes | |
| BYTE CBinaryFileReader::GetUChar() | |
| { | |
| if (m_lPos >= m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| BYTE res = *m_pDataCur; | |
| ++m_lPos; | |
| ++m_pDataCur; | |
| return res; | |
| } | |
| signed char CBinaryFileReader::GetChar() | |
| { | |
| if (m_lPos >= m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| BYTE res = *m_pDataCur; | |
| if (res > 127) | |
| res -= 256; | |
| ++m_lPos; | |
| ++m_pDataCur; | |
| return res; | |
| } | |
| // 1 bytes | |
| BYTE CBinaryFileReader::GetUChar_TypeNode() | |
| { | |
| if (m_lPos >= m_lSize) | |
| return NSBinPptxRW::g_nodeAttributeEnd; | |
| BYTE res = *m_pDataCur; | |
| ++m_lPos; | |
| ++m_pDataCur; | |
| return res; | |
| } | |
| bool CBinaryFileReader::GetBool() | |
| { | |
| return (GetUChar() != 0) ? true : false; | |
| } | |
| // 2 byte | |
| _UINT16 CBinaryFileReader::GetUShort() | |
| { | |
| if (m_lPos + 1 >= m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| _UINT16 res = 0; | |
| memcpy(&res, m_pDataCur, sizeof(_UINT16)); | |
| #else | |
| _UINT16 res = *((_UINT16*)m_pDataCur); // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPos += 2; | |
| m_pDataCur += 2; | |
| return res; | |
| } | |
| _INT16 CBinaryFileReader::GetShort() | |
| { | |
| if (m_lPos + 1 >= m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| _INT16 res = 0; | |
| memcpy(&res, m_pDataCur, sizeof(_INT16)); | |
| #else | |
| _INT16 res = *((_INT16*)m_pDataCur); // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPos += 2; | |
| m_pDataCur += 2; | |
| return res; | |
| } | |
| // 4 byte | |
| _UINT32 CBinaryFileReader::GetULong() | |
| { | |
| if (m_lPos + 3 >= m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| _UINT32 res = 0; | |
| memcpy(&res, m_pDataCur, sizeof(_UINT32)); | |
| #else | |
| _UINT32 res = *((_UINT32*)m_pDataCur); // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPos += 4; | |
| m_pDataCur += 4; | |
| return res; | |
| } | |
| _INT64 CBinaryFileReader::GetLong64() | |
| { | |
| if (m_lPos + 7 >= m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| _INT64 res = 0; | |
| memcpy(&res, m_pDataCur, sizeof(_INT64)); | |
| #else | |
| _INT64 res = *((_INT64*)m_pDataCur); // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPos += 8; | |
| m_pDataCur += 8; | |
| return res; | |
| } | |
| _INT32 CBinaryFileReader::GetLong() | |
| { | |
| return (_INT32)GetULong(); | |
| } | |
| double CBinaryFileReader::GetDouble() | |
| { | |
| return 1.0 * GetLong() / 100000; | |
| } | |
| double CBinaryFileReader::GetDouble64() | |
| { | |
| return 1.0 * GetLong64() / 100000; | |
| } // 8 byte | |
| double CBinaryFileReader::GetDoubleReal() | |
| { | |
| if (m_lPos + (int)DOUBLE_SIZEOF > m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| #if defined(_IOS) || defined(__ANDROID__) | |
| double res = 0.0; | |
| memcpy(&res, m_pDataCur, sizeof(double)); | |
| #else | |
| double res = *((double*)m_pDataCur); // EXC_ARM_DA_ALIGN on ios | |
| #endif | |
| m_lPos += DOUBLE_SIZEOF; | |
| m_pDataCur += DOUBLE_SIZEOF; | |
| return res; | |
| } | |
| //String | |
| std::wstring CBinaryFileReader::GetString(_INT32 len) | |
| { | |
| len *= 2; | |
| return GetString3(len); | |
| } | |
| std::string CBinaryFileReader::GetString1(_INT32 len) | |
| { | |
| if (len < 1 ) | |
| return ""; | |
| if (m_lPos + len > m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| std::string res((CHAR*)m_pDataCur, len); | |
| m_lPos += len; | |
| m_pDataCur += len; | |
| return res; | |
| } | |
| std::wstring CBinaryFileReader::GetString2() | |
| { | |
| _INT32 len = GetLong(); | |
| return GetString(len); | |
| } | |
| std::wstring CBinaryFileReader::GetString3(_INT32 len)//len in byte for utf16 | |
| { | |
| if (len < 1 ) | |
| return _T(""); | |
| if (m_lPos + len > m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| _UINT32 lSize = len >>1; //string in char | |
| if (sizeof(wchar_t) == 4) | |
| { | |
| std::wstring val = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)m_pDataCur, lSize); | |
| std::wstring res(val.c_str(), val.length()); | |
| m_lPos += len; | |
| m_pDataCur += len; | |
| return res; | |
| } | |
| else | |
| { | |
| std::wstring res((WCHAR*)m_pDataCur, lSize); | |
| m_lPos += len; | |
| m_pDataCur += len; | |
| return res; | |
| } | |
| } | |
| std::wstring CBinaryFileReader::GetString4(_INT32 len)//len in byte for utf16 | |
| { | |
| if (len < 1) | |
| return _T(""); | |
| if (m_lPos + len > m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| _UINT32 lSize = len >> 1; //string in char | |
| std::wstring res = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)m_pDataCur, lSize); | |
| m_lPos += len; | |
| m_pDataCur += len; | |
| return res; | |
| } | |
| bool CBinaryFileReader::GetArray(BYTE **pBuffer, _INT32 len) | |
| { | |
| if (0 == len) | |
| return false; | |
| if (m_lPos + len > m_lSize) | |
| return false; | |
| *pBuffer = new BYTE [len]; | |
| memcpy(pBuffer, m_pDataCur, len); | |
| m_lPos += len; | |
| m_pDataCur += len; | |
| return true; | |
| } | |
| /*LPSAFEARRAY CBinaryFileReader::GetArray(_INT32 len) | |
| { | |
| if (0 == len) | |
| return NULL; | |
| if (m_lPos + len > m_lSize) | |
| return NULL; | |
| SAFEARRAY* pArray = SafeArrayCreateVector(VT_UI1, (_UINT32)len); | |
| BYTE* pDataD = (BYTE*)pArray->pvData; | |
| memcpy(pDataD, m_pDataCur, len); | |
| m_lPos += len; | |
| m_pDataCur += len; | |
| return pArray; | |
| } | |
| */ | |
| std::string CBinaryFileReader::GetString2A() | |
| { | |
| _INT32 len = GetULong(); | |
| return GetString1(len); | |
| } | |
| void CBinaryFileReader::SkipRecord() | |
| { | |
| _INT32 _len = GetULong(); | |
| Skip(_len); | |
| } | |
| LONG CBinaryFileReader::GetPos() | |
| { | |
| return m_lPos; | |
| } | |
| LONG CBinaryFileReader::GetSize() | |
| { | |
| return m_lSize; | |
| } | |
| BYTE* CBinaryFileReader::GetData() | |
| { | |
| return m_pData; | |
| } | |
| BYTE* CBinaryFileReader::GetPointer(int nSize = 0) | |
| { | |
| if (nSize < 0) return 0; | |
| if (m_lPos + nSize > m_lSize) | |
| { | |
| std::cerr << "CBinaryFileReader out_of_range"<< std::endl; | |
| throw std::out_of_range("CBinaryFileReader out_of_range"); | |
| } | |
| BYTE* res = (BYTE*)m_pDataCur; | |
| m_lPos += nSize; | |
| m_pDataCur += nSize; | |
| return res; | |
| } | |
| _UINT16 CBinaryFileReader::XlsbReadRecordType() | |
| { | |
| _UINT16 nValue = GetUChar(); | |
| if(0 != (nValue & 0x80)) | |
| { | |
| BYTE nPart = GetUChar(); | |
| nValue = (nValue & 0x7F) | ((nPart & 0x7F) << 7); | |
| } | |
| return nValue; | |
| } | |
| void CBinaryFileReader::XlsbSkipRecord() | |
| { | |
| Skip(XlsbReadRecordLength()); | |
| } | |
| _UINT32 CBinaryFileReader::XlsbReadRecordLength() | |
| { | |
| _UINT16 nValue = 0; | |
| for (int i = 0; i < 4; ++i) | |
| { | |
| BYTE nPart = GetUChar(); | |
| nValue |= (nPart & 0x7F) << (7 * i); | |
| if(0 == (nPart & 0x80)) | |
| { | |
| break; | |
| } | |
| } | |
| return nValue; | |
| } | |
| } |