diff --git a/ASCOfficeDocxFile2/DocWrapper/DocxSerializer.cpp b/ASCOfficeDocxFile2/DocWrapper/DocxSerializer.cpp index d1cd71fd23..edf2ebad62 100644 --- a/ASCOfficeDocxFile2/DocWrapper/DocxSerializer.cpp +++ b/ASCOfficeDocxFile2/DocWrapper/DocxSerializer.cpp @@ -51,6 +51,130 @@ int BinDocxRW::g_nCurFormatVersion = 0; +namespace BinDocxRW +{ + class CPackageFile + { + public: + CPackageFile() {} + virtual ~CPackageFile() {} + + bool unpackage(const std::wstring& sSrcFileName, const std::wstring& sDstPath) + { + m_sDestPath = sDstPath; + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(sSrcFileName)) + return false; + + if (!oReader.ReadNextNode()) + return false; + + std::wstring sName = oReader.GetName(); + if (L"pkg:package" != sName) + return false; + + int nDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nDepth)) + { + sName = oReader.GetName(); + + if (L"pkg:part" == sName) + { + read_package_part(oReader); + } + } + + m_oContentTypes.Write(m_sDestPath); + return true; + } + private: + std::wstring m_sDestPath; + OOX::CContentTypes m_oContentTypes; + + void read_package_part(XmlUtils::CXmlLiteReader &oReader) + { + nullable_int padding; + nullable_string compression; + nullable_string contentType; + nullable_string name; + + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, L"pkg:name", name) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pkg:contentType", contentType) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pkg:padding", padding) + WritingElement_ReadAttributes_Read_else_if(oReader, L"pkg:compression", compression) + WritingElement_ReadAttributes_End(oReader) + + if (name.IsInit() == false) return; + + if (contentType.IsInit()) + { + m_oContentTypes.Registration(*contentType, L"", *name); + } + + int nDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"pkg:xmlData" == sName) + { + std::wstring data = oReader.GetInnerXml(); + WriteXmlFile(*name, data); + } + if (L"pkg:binaryData" == sName) + { + std::string data = oReader.GetText2A(); + WriteBinaryFile(*name, data, compression.IsInit() ? compression.get() : L""); + } + } + } + void WriteXmlFile(const std::wstring & name, std::wstring & data) + { + if (name.empty()) return; + + OOX::CPath path(m_sDestPath + name); + + NSDirectory::CreateDirectories(path.GetDirectory()); + + NSFile::CFileBinary file; + if (file.CreateFileW(path.GetPath())) + { + file.WriteStringUTF8(data); + file.CloseFile(); + } + } + void WriteBinaryFile(const std::wstring & name, std::string & data, const std::wstring & compression) + { + if (name.empty()) return; + + OOX::CPath path(m_sDestPath + name); + + NSDirectory::CreateDirectories(path.GetDirectory()); + + NSFile::CFileBinary file; + if (file.CreateFileW(path.GetPath())) + { + BYTE* pDstBuffer = NULL; + int dstLen = Base64::Base64DecodeGetRequiredLength((int)data.size()); + + pDstBuffer = new BYTE[dstLen]; + if (pDstBuffer) + { + Base64::Base64Decode(data.c_str(), (int)data.size(), pDstBuffer, &dstLen); + + file.WriteFile(pDstBuffer, (DWORD)dstLen); + file.CloseFile(); + + delete []pDstBuffer; + } + } + } + }; +} + BinDocxRW::CDocxSerializer::CDocxSerializer() { m_pParamsWriter = NULL; @@ -148,7 +272,6 @@ bool BinDocxRW::CDocxSerializer::saveToFile(const std::wstring& sSrcFileName, co RELEASEOBJECT(pFontPicker); return true; } - bool BinDocxRW::CDocxSerializer::CreateDocxFolders(std::wstring strDirectory, std::wstring& sThemePath, std::wstring& sMediaPath, std::wstring& sEmbedPath) { bool res = true; @@ -481,3 +604,10 @@ void BinDocxRW::CDocxSerializer::setSaveChartAsImg(bool bSaveChartAsImg) { m_bSaveChartAsImg = bSaveChartAsImg; } + +bool BinDocxRW::CDocxSerializer::unpackageFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath) +{ + BinDocxRW::CPackageFile file; + + return file.unpackage(sSrcFileName, sDstPath); +} diff --git a/ASCOfficeDocxFile2/DocWrapper/DocxSerializer.h b/ASCOfficeDocxFile2/DocWrapper/DocxSerializer.h index da2f986244..aed6ad8feb 100644 --- a/ASCOfficeDocxFile2/DocWrapper/DocxSerializer.h +++ b/ASCOfficeDocxFile2/DocWrapper/DocxSerializer.h @@ -63,6 +63,8 @@ namespace BinDocxRW bool loadFromFile (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions, const std::wstring& sThemePath, const std::wstring& sMediaPath, const std::wstring& sEmbedPath); bool saveToFile (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions, const std::wstring& sTempPath); + + bool unpackageFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath); bool CreateDocxFolders(std::wstring strDirectory, std::wstring& sThemePath, std::wstring& sMediaPath, std::wstring& sEmbedPath); diff --git a/Common/DocxFormat/Source/DocxFormat/DocxFlat.cpp b/Common/DocxFormat/Source/DocxFormat/DocxFlat.cpp index 1650a7e6b7..ec354da19a 100644 --- a/Common/DocxFormat/Source/DocxFormat/DocxFlat.cpp +++ b/Common/DocxFormat/Source/DocxFormat/DocxFlat.cpp @@ -75,8 +75,8 @@ namespace OOX if ( oReader.IsEmptyNode() ) return; - int nStylesDepth = oReader.GetDepth(); - while ( oReader.ReadNextSiblingNode( nStylesDepth ) ) + int nDepth = oReader.GetDepth(); + while ( oReader.ReadNextSiblingNode(nDepth) ) { std::wstring sName = oReader.GetName(); diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index ce23347d13..97a0b0d661 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -787,6 +787,7 @@ bool COfficeFileFormatChecker::isOOXFlatFormatFile(unsigned char* pBuffer,int dw const char *docxFormatLine = "xmlns:w=\"http://schemas.microsoft.com/office/word/2003/wordml\""; const char *xlsxFormatLine = "xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\""; + const char *packageFormatLine = "xmlns:pkg=\"http://schemas.microsoft.com/office/2006/xmlPackage\""; if (std::string::npos != xml_string.find(docxFormatLine)) { @@ -796,7 +797,10 @@ bool COfficeFileFormatChecker::isOOXFlatFormatFile(unsigned char* pBuffer,int dw { nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT; } - + else if (std::string::npos != xml_string.find(packageFormatLine)) + { + nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PACKAGE; + } if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) return true; return false; diff --git a/Common/OfficeFileFormats.h b/Common/OfficeFileFormats.h index 3d4ce6f294..8847e85cac 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -52,6 +52,7 @@ #define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0010 #define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0011 #define AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0012 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_PACKAGE AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0013 #define AVS_OFFICESTUDIO_FILE_PRESENTATION 0x0080 #define AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0001 diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index d728663df2..7b4c3a3b70 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -131,6 +131,67 @@ namespace NExtractTools } return hRes; } + _UINT32 package2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params) + { + std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); + + NSDirectory::CreateDirectory(sResultDocxDir); + + _UINT32 nRes = package2docx_dir(sFrom, sResultDocxDir, sTemp, params); + + if (SUCCEEDED_X2T(nRes)) + { + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDocxDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + + return nRes; + } + _UINT32 package2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params) + { + std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked"); + std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin"); + + NSDirectory::CreateDirectory(sResultDoctDir); + + _UINT32 nRes = package2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params); + + if (SUCCEEDED_X2T(nRes)) + { + COfficeUtils oCOfficeUtils(NULL); + nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT; + } + + return nRes; + } + _UINT32 package2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params) + { + std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked"); + + NSDirectory::CreateDirectory(sResultDocxDir); + + _UINT32 nRes = package2docx_dir(sFrom, sResultDocxDir, sTemp, params); + + if (SUCCEEDED_X2T(nRes)) + { + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + m_oCDocxSerializer.setIsNoBase64(params.getIsNoBase64()); + m_oCDocxSerializer.setFontDir(params.getFontPath()); + + nRes = m_oCDocxSerializer.saveToFile(sTo, sResultDocxDir, params.getXmlOptions(), sTemp) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + } + + return nRes; + } + _UINT32 package2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params) + { + BinDocxRW::CDocxSerializer m_oCDocxSerializer; + + _UINT32 nRes = m_oCDocxSerializer.unpackageFile(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + + return nRes; + } // docxflat -> bin _UINT32 docxflat2doct_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params) { @@ -2740,6 +2801,19 @@ namespace NExtractTools { return pptx2pptt_bin(sResultDecryptFile, sTo, sTemp,params); }break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT: + { + return docxflat2doct_bin(sResultDecryptFile, sTo, sTemp, params); + }break; + case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT: + { + const std::wstring & sXmlOptions = params.getXmlOptions(); + return xlsxflat2xlst_bin(sResultDecryptFile, sTo, sTemp, params); + }break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_PACKAGE: + { + return package2doct_bin(sResultDecryptFile, sTo, sTemp, params); + }break; } } return AVS_FILEUTILS_ERROR_CONVERT; diff --git a/X2tConverter/src/ASCConverters.h b/X2tConverter/src/ASCConverters.h index 43128f4306..0139c062b9 100644 --- a/X2tConverter/src/ASCConverters.h +++ b/X2tConverter/src/ASCConverters.h @@ -59,6 +59,11 @@ namespace NExtractTools _UINT32 docxflat2doct (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params); _UINT32 docxflat2doct_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params); + _UINT32 package2docx (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params); + _UINT32 package2docx_dir (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params); + _UINT32 package2doct (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params); + _UINT32 package2doct_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params); + _UINT32 dotm2docm (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params); _UINT32 dotm2docm_dir (const std::wstring &sFrom, const std::wstring &sTo, InputParams& params); _UINT32 dotx2docx (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params); diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index 42833f72be..078f6e6860 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -131,9 +131,15 @@ namespace NExtractTools }break; case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT: { - if (0 == sExt2.compare(_T(".doct"))) res = TCD_DOCXFLAT2DOCT; - else if (0 == sExt2.compare(_T(".bin"))) res = TCD_DOCXFLAT2DOCT_BIN; + if (0 == sExt2.compare(_T(".doct"))) res = TCD_PKG2DOCT; + else if (0 == sExt2.compare(_T(".bin"))) res = TCD_PKG2DOCT_BIN; + else if (0 == sExt2.compare(_T(".docx"))) res = TCD_PKG2DOCX; }break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_PACKAGE: + { + if (0 == sExt2.compare(_T(".doct"))) res = TCD_DOCXFLAT2DOCT; + else if (0 == sExt2.compare(_T(".bin"))) res = TCD_DOCXFLAT2DOCT_BIN; + }break; case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT: { if (0 == sExt2.compare(_T(".xlst"))) res = TCD_XLSXFLAT2XLST; diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index ee25e9f6f1..e08b615591 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -75,6 +75,10 @@ namespace NExtractTools TCD_DOCXFLAT2DOCT, TCD_DOCXFLAT2DOCT_BIN, + TCD_PKG2DOCX, + TCD_PKG2DOCT, + TCD_PKG2DOCT_BIN, + TCD_XLSXFLAT2XLST, TCD_XLSXFLAT2XLST_BIN,