/* * (c) Copyright Ascensio System SIA 2010-2023 * * 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-6 Ernesta Birznieka-Upish * 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 "WorkBookStream.h" #include "Biff12_records/CommonRecords.h" #include "Biff12_records/BeginBook.h" #include "Biff12_records/FileVersion.h" #include "Biff12_records/FileSharingIso.h" #include "Biff12_records/WbProp.h" #include "Biff12_unions/ACABSPATH.h" #include "Biff12_unions/BOOKVIEWS.h" #include "Biff12_unions/BUNDLESHS.h" #include "Biff12_unions/FNGROUP.h" #include "Biff12_unions/EXTERNALS.h" #include "Biff12_records/CalcProp.h" #include "Biff12_unions/PIVOTCACHEIDS.h" #include "Biff12_records/OleSize.h" #include "Biff12_records/EndBook.h" #include "Biff12_records/BookProtection.h" #include "Biff12_records/BookProtectionIso.h" #include "Biff12_records/SupBookSrc.h" #include "Biff12_unions/SUP.h" #include "Biff12_unions/FRT.h" #include "Biff12_unions/FRTWORKBOOK.h" using namespace XLS; namespace XLSB { WorkBookStream::WorkBookStream() { } WorkBookStream::~WorkBookStream() { } BaseObjectPtr WorkBookStream::clone() { return BaseObjectPtr(new WorkBookStream(*this)); } const bool WorkBookStream::loadContent(BinProcessor& proc) { int count = 0; while (true) { CFRecordType::TypeId type = proc.getNextRecordType(); if (type == rt_NONE) break; switch(type) { case rt_BeginBook: { if (proc.optional()) { m_bBeginBook = true; elements_.pop_back(); } else m_bBeginBook = false; }break; case rt_FileVersion: { if (proc.optional()) { m_BrtFileVersion = elements_.back(); elements_.pop_back(); } }break; case rt_FileSharingIso: { if (proc.optional()) { m_BrtFileSharingIso = elements_.back(); elements_.pop_back(); } }break; case rt_FileSharing: { if (proc.optional()) { m_BrtFileSharing = elements_.back(); elements_.pop_back(); } }break; case rt_WbProp: { if (proc.optional()) { m_BrtWbProp = elements_.back(); elements_.pop_back(); } }break; case rt_BookProtectionIso: { if (proc.optional()) { m_BrtBookProtectionIso = elements_.back(); elements_.pop_back(); } }break; case rt_BookProtection: { if (proc.optional()) { m_BrtBookProtection = elements_.back(); elements_.pop_back(); } }break; case rt_ACBegin: { if (proc.optional()) { m_ACABSPATH = elements_.back(); elements_.pop_back(); } }break; case rt_BeginBookViews: { if (proc.optional()) { m_BOOKVIEWS = elements_.back(); elements_.pop_back(); } }break; case rt_BeginBundleShs: { if (proc.optional()) { m_BUNDLESHS = elements_.back(); elements_.pop_back(); } }break; case rt_BeginFnGroup: { if (proc.optional()) { m_FNGROUP = elements_.back(); elements_.pop_back(); } }break; case rt_BeginExternals: { if (proc.optional()) { m_EXTERNALS = elements_.back(); elements_.pop_back(); } }break; case rt_Name: { count = proc.repeated(0, 0); int start_pos = m_arBrtName.size(); while(count > 0) { m_arBrtName.insert(m_arBrtName.begin() + start_pos, elements_.back()); elements_.pop_back(); count--; } }break; case rt_CalcProp: { if (proc.optional()) { m_BrtCalcProp = elements_.back(); elements_.pop_back(); } }break; case rt_OleSize: { if (proc.optional()) { m_BrtOleSize = elements_.back(); elements_.pop_back(); } }break; case rt_BeginPivotCacheIDs: { if (proc.optional()) { m_PIVOTCACHEIDS = elements_.back(); elements_.pop_back(); } }break; case rt_UserBookView: { while (true) { if(proc.optional()) { m_arBrtUserBookView.push_back(elements_.back()); elements_.pop_back(); while (proc.optional()) { //m_arFRT.push_back(elements_.back()); elements_.pop_back(); } } else break; } }break; case rt_WebOpt: { if (proc.optional()) { m_BrtWebOpt = elements_.back(); elements_.pop_back(); } }break; case rt_FileRecover: { count = proc.repeated(0, 0); while(count > 0) { m_arBrtFileRecover.insert(m_arBrtFileRecover.begin(), elements_.back()); elements_.pop_back(); count--; } }break; case rt_FRTBegin: { FRTWORKBOOK oFRTWORKBOOK; if (proc.optional(oFRTWORKBOOK)) { if(m_FRTWORKBOOK != nullptr) { if(oFRTWORKBOOK.m_SLICERCACHEIDS != nullptr) boost::dynamic_pointer_cast(m_FRTWORKBOOK)->m_SLICERCACHEIDS = oFRTWORKBOOK.m_SLICERCACHEIDS; if(oFRTWORKBOOK.m_SLICERCACHESPIVOTCACHEIDS != nullptr) boost::dynamic_pointer_cast(m_FRTWORKBOOK)->m_SLICERCACHESPIVOTCACHEIDS = oFRTWORKBOOK.m_SLICERCACHESPIVOTCACHEIDS; if(oFRTWORKBOOK.m_TABLESLICERCACHEIDS != nullptr) boost::dynamic_pointer_cast(m_FRTWORKBOOK)->m_TABLESLICERCACHEIDS = oFRTWORKBOOK.m_TABLESLICERCACHEIDS; elements_.pop_back(); } else { m_FRTWORKBOOK = elements_.back(); elements_.pop_back(); } } }break; case rt_EndBook: { if (proc.optional()) { m_bEndBook = true; elements_.pop_back(); } else m_bEndBook = false; }break; default://skip { proc.SkipRecord(); }break; } } return true; } const bool WorkBookStream::saveContent(XLS::BinProcessor & proc) { proc.mandatory(); if (m_BrtFileVersion != nullptr) proc.mandatory(*m_BrtFileVersion); if (m_BrtFileSharingIso != nullptr) proc.mandatory(*m_BrtFileSharingIso); if (m_BrtFileSharing != nullptr) proc.mandatory(*m_BrtFileSharing); if (m_BrtWbProp != nullptr) proc.mandatory(*m_BrtWbProp); if (m_BrtBookProtectionIso != nullptr) proc.mandatory(*m_BrtBookProtectionIso); if (m_BrtBookProtection != nullptr) proc.mandatory(*m_BrtBookProtection); if (m_ACABSPATH != nullptr) proc.mandatory(*m_ACABSPATH); if (m_BOOKVIEWS != nullptr) proc.mandatory(*m_BOOKVIEWS); if (m_BUNDLESHS != nullptr) proc.mandatory(*m_BUNDLESHS); if (m_FNGROUP != nullptr) proc.mandatory(*m_FNGROUP); if (m_EXTERNALS != nullptr) proc.mandatory(*m_EXTERNALS); for(auto &item: m_arBrtName) { proc.mandatory(*item); } if (m_BrtCalcProp != nullptr) proc.mandatory(*m_BrtCalcProp); if (m_BrtOleSize != nullptr) proc.mandatory(*m_BrtOleSize); if (m_PIVOTCACHEIDS != nullptr) proc.mandatory(*m_PIVOTCACHEIDS); for (auto &item : m_arBrtUserBookView) { proc.mandatory(*item); } if (m_BrtWebOpt != nullptr) proc.mandatory(*m_BrtWebOpt); for (auto &item : m_arBrtFileRecover) { proc.mandatory(*item); } if (m_FRTWORKBOOK != nullptr) proc.mandatory(*m_FRTWORKBOOK); proc.mandatory(); return true; } void WorkBookStream::UpdateXtiWrite(XLS::GlobalWorkbookInfo* global_info_) { EXTERNALS* externals = dynamic_cast(m_EXTERNALS.get()); if (externals && !externals->m_arSUP.empty()) { if(externals->m_BrtExternSheet == nullptr) externals->m_BrtExternSheet = XLS::BaseObjectPtr(new XLSB::ExternSheet()); XLSB::ExternSheet* extern_sheet = dynamic_cast(externals->m_BrtExternSheet.get()); for (size_t i = 0; extern_sheet && i < externals->m_arSUP.size(); i++) { SUP* index_book = dynamic_cast(externals->m_arSUP[i].get()); if (!index_book) continue; if (index_book->m_source->get_type() == XLS::typeSupSelf) { XTIPtr xti(new XTI); xti->iSupBook = i; xti->itabFirst = 0; xti->itabLast = 0; extern_sheet->rgXTI.push_back(xti); } } for (size_t i = 0; extern_sheet && i < extern_sheet->rgXTI.size(); i++) { XTI* xti = dynamic_cast(extern_sheet->rgXTI[i].get()); if (!xti) continue; SUP* index_book = dynamic_cast(externals->m_arSUP[xti->iSupBook].get()); if (!index_book) continue; //if (index_book->arNames.empty()) continue; GlobalWorkbookInfo::_xti val_1; val_1.iSup = xti->iSupBook; val_1.pNames = &index_book->arNames; if (index_book->m_source->get_type() == XLS::typeSupBookSrc) { val_1.link = dynamic_cast(index_book->m_source.get())->strRelID.value.value(); val_1.itabFirst = xti->itabFirst; val_1.itabLast = xti->itabLast; } else if (xti->itabFirst >= 0 /*|| itabLast >= 0*/) { std::wstring strRange; if (-1 == xti->itabFirst) { strRange = L"#REF"; } else if (xti->itabFirst < global_info_->sheets_info.size()) { strRange = XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabFirst].name, L""); if (xti->itabFirst != xti->itabLast) { strRange += std::wstring(L":") + XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabLast].name, L""); } } val_1.link = strRange; } else if (xti->itabFirst == -1) { //sheet not found } else if (xti->itabFirst == -2) { //Workbook-level } global_info_->arXti_External.push_back(val_1); GlobalWorkbookInfo::arXti_External_static.push_back(val_1); } //global_info_->arXti.push_back(val); //} } } void WorkBookStream::UpdateXti(XLS::GlobalWorkbookInfo* global_info_) { EXTERNALS* externals = dynamic_cast(m_EXTERNALS.get()); if (externals) { //for (size_t s = 0; s < externals->m_arSUP.size(); s++) //{ // SUP* SUPP = dynamic_cast(externals->m_arSUP[s].get()); // if (!SUPP) continue; XLSB::ExternSheet* extern_sheet = dynamic_cast(externals->m_BrtExternSheet.get()); //GlobalWorkbookInfo::_xti val; //val.iSup = s; //val.pNames = &SUPP->arNames; for (size_t i = 0; extern_sheet && i < extern_sheet->rgXTI.size(); i++) { XTI* xti = dynamic_cast(extern_sheet->rgXTI[i].get()); if (!xti) continue; if(externals->m_arSUP.size() <= xti->iSupBook) continue; SUP* index_book = dynamic_cast(externals->m_arSUP[xti->iSupBook].get()); if (!index_book) continue; //if (index_book->arNames.empty()) continue; GlobalWorkbookInfo::_xti val_1; val_1.iSup = xti->iSupBook; auto namesVector = new std::vector(); *namesVector = index_book->arNames; val_1.pNames = namesVector; if(index_book->m_source->get_type() == XLS::typeSupBookSrc) { val_1.link = dynamic_cast(index_book->m_source.get())->strRelID.value.value(); val_1.itabFirst = xti->itabFirst; val_1.itabLast = xti->itabLast; } else if (xti->itabFirst >= 0 /*|| itabLast >= 0*/) { std::wstring strRange; if(-1 == xti->itabFirst) { strRange = L"#REF"; } else if (xti->itabFirst < global_info_->sheets_info.size()) { strRange = XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabFirst].name, L""); if (xti->itabFirst != xti->itabLast && xti->itabLast < global_info_->sheets_info.size()) { strRange += std::wstring(L":") + XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabLast].name, L""); } } val_1.link = strRange; } else if (xti->itabFirst == -1) { //sheet not found } else if (xti->itabFirst == -2) { //Workbook-level } global_info_->arXti_External.push_back(val_1); } //global_info_->arXti.push_back(val); //} } } void WorkBookStream::UpdateDefineNames(XLS::GlobalWorkbookInfo* global_info_) { for (size_t s = 0; s < m_arBrtName.size(); s++) { //LBL* LBL_ = dynamic_cast(m_arBrtName[s].get()); //if (!LBL_) continue; Name *lbl = dynamic_cast(m_arBrtName[s].get()); if (!lbl) continue; std::wstring name; std::wstring comment; //if (lbl->fBuiltin) name = lbl->name.value(); //if (name.empty()) name = lbl->Name_bin.value(); //NameCmt *namecmt = dynamic_cast(LBL_->m_NameCmt.get()); //if (namecmt) // { // if (name.empty()) //name = namecmt->name.value(); comment = lbl->comment.value(); //} std::wstring value = lbl->rgce.getAssembledFormula(lbl->fWorkbookParam/*lbl->itab == 0 ? true : false*/); if (!value.empty() && !name.empty() && lbl->itab != 0xFFFFFFFF) { int ind_sheet = lbl->itab; std::map>::iterator it = global_info_->mapDefineNames.find(name); if (it != global_info_->mapDefineNames.end()) { while ( it->second.size() <= ind_sheet) { it->second.push_back(L""); } it->second[ind_sheet] = value; //it->second.push_back(value); } else { std::vector ar(ind_sheet + 1); ar[ind_sheet] = value; //ar.push_back(value); global_info_->mapDefineNames.insert(std::make_pair(name, ar)); } //LBL_->isSerialize = true; } else { if (lbl->fFunc) { if (name != L"CHISQDIST" && name != L"CHISQINV" && name != L"CURRENT" && name != L"EFFECTIVE" && name.substr(0, 6) != L"_xlfn.") name = L"_xludf." + name; } } global_info_->arDefineNames.push_back(name);// для имен функций - todooo ... не все функции корректны !! БДИ !! } } } // namespace XLSB