From 64c74192c78425a07a17e5946826eef386d3816b Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Thu, 20 Mar 2025 16:09:36 +0500 Subject: [PATCH 001/114] FIx bug #73451 --- OdfFile/Writer/Format/odf_drawing_context.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index a696d1aa36..083707d3cf 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -637,6 +637,8 @@ void odf_drawing_context::end_drawing() draw->common_draw_attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.drawooo_display_ = L"printer"; // L"none" ??? if (!impl_->current_drawing_state_.xml_id_.empty()) draw->xml_id_ = impl_->current_drawing_state_.xml_id_; + if (impl_->anchor_settings_.style_wrap_) + impl_->current_graphic_properties->style_wrap_ = *impl_->anchor_settings_.style_wrap_; std::wstring strTransform; From 7857106d7645f46115954944f2048ec67edb6091 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Fri, 21 Mar 2025 13:43:19 +0500 Subject: [PATCH 002/114] Fix bug #73585 --- OdfFile/Writer/Converter/DocxConverter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OdfFile/Writer/Converter/DocxConverter.cpp b/OdfFile/Writer/Converter/DocxConverter.cpp index 1642cfd3a3..91dce02532 100644 --- a/OdfFile/Writer/Converter/DocxConverter.cpp +++ b/OdfFile/Writer/Converter/DocxConverter.cpp @@ -1608,6 +1608,9 @@ void DocxConverter::convert(OOX::Logic::CParagraphProperty *oox_paragraph_pr, convert(oox_paragraph_pr->m_oJc.GetPointer(), paragraph_properties->fo_text_align_); + if (!oox_paragraph_pr->m_oJc.GetPointer() && oox_paragraph_pr->m_oBidi.IsInit()) + paragraph_properties->fo_text_align_ = odf_types::text_align(odf_types::text_align::End); + if (oox_paragraph_pr->m_oTextAlignment.IsInit() && oox_paragraph_pr->m_oTextAlignment->m_oVal.IsInit()) { //switch(oox_paragraph_pr->m_oTextAlignment->m_oVal->GetValue()) From e8f88ab20d17982713d6081d731ffe5a9d33bd4e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 24 Mar 2025 18:42:03 +0600 Subject: [PATCH 003/114] Add globals xls writing --- .../Format/Logic/Biff_records/CalcCount.cpp | 4 +++ .../Format/Logic/Biff_records/CalcCount.h | 3 +- .../Format/Logic/Biff_records/CalcDelta.cpp | 6 ++++ .../Format/Logic/Biff_records/CalcDelta.h | 3 +- .../Format/Logic/Biff_records/CalcIter.cpp | 4 +++ .../Format/Logic/Biff_records/CalcIter.h | 4 +-- .../Logic/Biff_records/CalcSaveRecalc.cpp | 5 ++++ .../Logic/Biff_records/CalcSaveRecalc.h | 3 +- .../Logic/Biff_records/DefaultRowHeight.cpp | 13 +++++++++ .../Logic/Biff_records/DefaultRowHeight.h | 11 +++---- .../Format/Logic/Biff_records/GridSet.cpp | 5 ++++ .../Format/Logic/Biff_records/GridSet.h | 1 + .../Format/Logic/Biff_records/Guts.cpp | 6 ++++ .../XlsFile/Format/Logic/Biff_records/Guts.h | 5 ++-- .../Biff_records/HorizontalPageBreaks.cpp | 9 ++++++ .../Logic/Biff_records/HorizontalPageBreaks.h | 3 +- .../Format/Logic/Biff_records/PrintGrid.cpp | 7 +++++ .../Format/Logic/Biff_records/PrintGrid.h | 4 ++- .../Format/Logic/Biff_records/PrintRowCol.cpp | 5 ++++ .../Format/Logic/Biff_records/PrintRowCol.h | 3 +- .../Logic/Biff_records/VerticalPageBreaks.cpp | 9 ++++++ .../Logic/Biff_records/VerticalPageBreaks.h | 2 +- .../Format/Logic/Biff_records/WsBool.cpp | 19 ++++++++++++ .../Format/Logic/Biff_records/WsBool.h | 23 ++++++++------- .../Format/Logic/Biff_structures/HorzBrk.cpp | 4 +++ .../Format/Logic/Biff_structures/HorzBrk.h | 7 +++-- .../Format/Logic/Biff_structures/VertBrk.cpp | 4 +++ .../Format/Logic/Biff_structures/VertBrk.h | 8 +++-- .../Format/Logic/Biff_unions/GLOBALS.cpp | 29 +++++++++++++++++++ .../Format/Logic/Biff_unions/GLOBALS.h | 1 + 30 files changed, 177 insertions(+), 33 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcCount.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcCount.cpp index bc7b49b090..c7d1a64734 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcCount.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcCount.cpp @@ -54,6 +54,10 @@ void CalcCount::readFields(CFRecord& record) { record >> cIter; } +void CalcCount::writeFields(CFRecord& record) +{ + record << cIter; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcCount.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcCount.h index d359819248..a4155e0ad8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcCount.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcCount.h @@ -47,11 +47,12 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCalcCount; //----------------------------- - _INT16 cIter; + _INT16 cIter = 100; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcDelta.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcDelta.cpp index a58af83b91..787349659a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcDelta.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcDelta.cpp @@ -37,6 +37,7 @@ namespace XLS CalcDelta::CalcDelta() { + numDelta.data.value = 0.001; } @@ -56,5 +57,10 @@ void CalcDelta::readFields(CFRecord& record) record >> numDelta; } +void CalcDelta::writeFields(CFRecord& record) +{ + record << numDelta; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcDelta.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcDelta.h index 41adabaa64..8913048df1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcDelta.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcDelta.h @@ -49,11 +49,12 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCalcDelta; //----------------------------- - Xnum numDelta; + Xnum numDelta; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcIter.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcIter.cpp index 076facf03b..9dfb419a7f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcIter.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcIter.cpp @@ -55,6 +55,10 @@ void CalcIter::readFields(CFRecord& record) { record >> vfIter; } +void CalcIter::writeFields(CFRecord& record) +{ + record << vfIter; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcIter.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcIter.h index a923fd4d8c..13607f51c1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcIter.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcIter.h @@ -48,13 +48,13 @@ public: BaseObjectPtr clone(); - + void writeFields(CFRecord& record); void readFields(CFRecord& record); static const ElementType type = typeCalcIter; //----------------------------- - Boolean vfIter; + Boolean vfIter = 0; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.cpp index b27229626c..8d8794ad4f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.cpp @@ -56,5 +56,10 @@ void CalcSaveRecalc::readFields(CFRecord& record) record >> fSaveRecalc; } +void CalcSaveRecalc::writeFields(CFRecord& record) +{ + record << fSaveRecalc; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.h index 36295d9945..b4a8cfcafc 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.h @@ -46,11 +46,12 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCalcSaveRecalc; //----------------------------- - Boolean fSaveRecalc; + Boolean fSaveRecalc = false; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.cpp index 32875fd981..b77db5ad46 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.cpp @@ -78,5 +78,18 @@ namespace XLS } } + + void DefaultRowHeight::writeFields(CFRecord& record) + { + unsigned short flags; + record >> flags; + + SETBIT(flags, 0, fUnsynced); + SETBIT(flags, 1, fDyZero); + SETBIT(flags, 2, fExAsc); + SETBIT(flags, 3, fExDsc); + + record << flags << miyRw; + } } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.h index efbe964a3b..1ef00388bd 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.h @@ -46,15 +46,16 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeDefaultRowHeight; //----------------------------- - bool fUnsynced; - bool fDyZero; - bool fExAsc; - bool fExDsc; + bool fUnsynced = false; + bool fDyZero = false; + bool fExAsc = false; + bool fExDsc = false; - _INT16 miyRw; // measured in twips (1/20 of of a printer's point) + _INT16 miyRw = 290; // measured in twips (1/20 of of a printer's point) }; class DefaultRowHeight_BIFF2 : public DefaultRowHeight diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/GridSet.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/GridSet.cpp index b5815c524c..83c8584aab 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/GridSet.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/GridSet.cpp @@ -56,5 +56,10 @@ void GridSet::readFields(CFRecord& record) record.skipNunBytes(2); // reserved } +void GridSet::writeFields(CFRecord& record) +{ + _UINT16 gridset = 1; // reserved + record << gridset; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/GridSet.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/GridSet.h index de10905864..e0bbaa9a97 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/GridSet.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/GridSet.h @@ -50,6 +50,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeGridSet; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Guts.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Guts.cpp index 13f531cbeb..17d03e5f7a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Guts.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Guts.cpp @@ -56,5 +56,11 @@ void Guts::readFields(CFRecord& record) record >> iLevelRwMac >> iLevelColMac; } +void Guts::writeFields(CFRecord& record) +{ + record.reserveNunBytes(4); // unused + record << iLevelRwMac << iLevelColMac; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Guts.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Guts.h index 7ea4a8dbe3..5111fa0134 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Guts.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Guts.h @@ -50,12 +50,13 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeGuts; //----------------------------- - _UINT16 iLevelRwMac; - _UINT16 iLevelColMac; + _UINT16 iLevelRwMac = 0; + _UINT16 iLevelColMac = 0; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HorizontalPageBreaks.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HorizontalPageBreaks.cpp index 22f8bf80ce..e63bbf2491 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HorizontalPageBreaks.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HorizontalPageBreaks.cpp @@ -52,6 +52,15 @@ namespace XLS rgbrk.push_back(hb); } } + void HorizontalPageBreaks::writeFields(CFRecord& record) + { + cbrk = rgbrk.size(); + record << cbrk; + for (auto i:rgbrk) + { + record << *i; + } + } int HorizontalPageBreaks::serialize(std::wostream & stream) { if (rgbrk.empty()) return 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HorizontalPageBreaks.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HorizontalPageBreaks.h index 8eba147c8d..8e668d86a1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HorizontalPageBreaks.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HorizontalPageBreaks.h @@ -48,12 +48,13 @@ namespace XLS BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeHorizontalPageBreaks; virtual int serialize(std::wostream & stream); //----------------------------- - _UINT16 cbrk; + _UINT16 cbrk = 0; BiffStructurePtrVector rgbrk; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintGrid.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintGrid.cpp index 7570f7eb95..b10058aeff 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintGrid.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintGrid.cpp @@ -57,5 +57,12 @@ void PrintGrid::readFields(CFRecord& record) fPrintGrid = GETBIT(flags, 0); } +void PrintGrid::writeFields(CFRecord& record) +{ + unsigned short flags = 0; + SETBIT(flags, 0, fPrintGrid); + record << flags; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintGrid.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintGrid.h index 65d88db077..a58aa70fa4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintGrid.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintGrid.h @@ -50,11 +50,13 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); + static const ElementType type = typePrintGrid; //----------------------------- - bool fPrintGrid; + bool fPrintGrid = false; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintRowCol.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintRowCol.cpp index 8eace8b2b4..06384f147e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintRowCol.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintRowCol.cpp @@ -55,5 +55,10 @@ void PrintRowCol::readFields(CFRecord& record) record >> printRwCol; } +void PrintRowCol::writeFields(CFRecord& record) +{ + record << printRwCol; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintRowCol.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintRowCol.h index f43e7d81ca..29ca12cd0e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintRowCol.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PrintRowCol.h @@ -50,12 +50,13 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typePrintRowCol; //----------------------------- - Boolean printRwCol; + Boolean printRwCol = false; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VerticalPageBreaks.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VerticalPageBreaks.cpp index 0947390f65..0b7ecfe2ff 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VerticalPageBreaks.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VerticalPageBreaks.cpp @@ -52,6 +52,15 @@ namespace XLS rgbrk.push_back(vb); } } + void VerticalPageBreaks::writeFields(CFRecord& record) + { + cbrk = rgbrk.size(); + record << cbrk; + for (auto i:rgbrk) + { + record << *i; + } + } int VerticalPageBreaks::serialize(std::wostream & stream) { if (rgbrk.empty()) return 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VerticalPageBreaks.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VerticalPageBreaks.h index 6403673a76..92d6bcebd1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VerticalPageBreaks.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VerticalPageBreaks.h @@ -47,7 +47,7 @@ namespace XLS BaseObjectPtr clone(); void readFields(CFRecord& record); - + void writeFields(CFRecord& record); static const ElementType type = typeVerticalPageBreaks; virtual int serialize(std::wostream & stream); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/WsBool.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/WsBool.cpp index 5880ebd290..6ca889e3fe 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/WsBool.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/WsBool.cpp @@ -67,6 +67,25 @@ void WsBool::readFields(CFRecord& record) fAltFormulaEntry = GETBIT(flags, 15); } +void WsBool::writeFields(CFRecord& record) +{ + unsigned short flags = 0; + + SETBIT(flags, 0, fShowAutoBreaks); + if(fDialog) + SETBIT(flags, 4, fDialog); + SETBIT(flags, 5, fApplyStyles); + SETBIT(flags, 6, fRowSumsBelow); + SETBIT(flags, 7, fColSumsRight); + SETBIT(flags, 8, fFitToPage); + SETBIT(flags, 10, fDspGuts); + SETBIT(flags, 12, fSyncHoriz); + SETBIT(flags, 13, fSyncVert); + SETBIT(flags, 14, fAltExprEval); + SETBIT(flags, 15, fAltFormulaEntry); + + record << flags; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/WsBool.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/WsBool.h index 5a69acde4b..6f00d14869 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/WsBool.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/WsBool.h @@ -47,21 +47,22 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeWsBool; //----------------------------- - bool fShowAutoBreaks; - bool& fDialog; - bool fApplyStyles; - bool fRowSumsBelow; - bool fColSumsRight; - bool fFitToPage; - bool fDspGuts; - bool fSyncHoriz; - bool fSyncVert; - bool fAltExprEval; - bool fAltFormulaEntry; + bool fShowAutoBreaks = true; + bool& fDialog; + bool fApplyStyles = false; + bool fRowSumsBelow = true; + bool fColSumsRight = true; + bool fFitToPage = false; + bool fDspGuts = true; + bool fSyncHoriz = false; + bool fSyncVert = false; + bool fAltExprEval = false; + bool fAltFormulaEntry = false; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HorzBrk.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HorzBrk.cpp index 895cac9184..0501c747d0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HorzBrk.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HorzBrk.cpp @@ -44,6 +44,10 @@ namespace XLS { record >> row >> colStart >> colEnd; } + void HorzBrk::save(CFRecord& record) + { + record << row << colStart << colEnd; + } int HorzBrk::serialize(std::wostream & stream) { CP_XML_WRITER(stream) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HorzBrk.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HorzBrk.h index 53e92e8888..2344b9bd81 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HorzBrk.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HorzBrk.h @@ -45,11 +45,12 @@ public: static const ElementType type = typeHorzBrk; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual int serialize(std::wostream & stream); - RwU row; - unsigned short colStart; - unsigned short colEnd; + RwU row = 0; + unsigned short colStart = 0; + unsigned short colEnd = 0; }; typedef boost::shared_ptr HorzBrkPtr; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/VertBrk.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/VertBrk.cpp index d963711c32..d4e9579552 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/VertBrk.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/VertBrk.cpp @@ -43,6 +43,10 @@ namespace XLS { record >> col >> rowStart >> rowEnd; } + void VertBrk::save(CFRecord& record) + { + record << col << rowStart << rowEnd; + } int VertBrk::serialize(std::wostream & stream) { CP_XML_WRITER(stream) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/VertBrk.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/VertBrk.h index 19217c5614..64481a34c5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/VertBrk.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/VertBrk.h @@ -44,11 +44,13 @@ namespace XLS static const ElementType type = typeVertBrk; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); + virtual int serialize(std::wostream & stream); - ColU col; - RwU rowStart; - RwU rowEnd; + ColU col = 0; + RwU rowStart = 0; + RwU rowEnd = 0; }; typedef boost::shared_ptr VertBrkPtr; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.cpp index c14eafcbeb..db68b33891 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.cpp @@ -156,6 +156,35 @@ const bool GLOBALS::loadContent(BinProcessor& proc) return true; } +const bool GLOBALS::saveContent(BinProcessor& proc) +{ + if(m_CalcMode != nullptr) + proc.mandatory(*m_CalcMode); + if(m_CalcMode != nullptr) + proc.mandatory(*m_CalcMode); + proc.optional(); + + if(m_CalcRefMode != nullptr) + proc.mandatory(*m_CalcRefMode); + proc.optional(); + proc.optional(); + proc.optional(); + proc.optional(); + proc.optional(); + proc.optional(); + + if(m_Guts != nullptr) + proc.mandatory(*m_Guts); + if(m_DefaultRowHeight != nullptr) + proc.mandatory(*m_DefaultRowHeight); + if(m_WsBool != nullptr) + proc.mandatory(*m_WsBool); + if(m_HorizontalPageBreaks != nullptr) + proc.mandatory(*m_HorizontalPageBreaks); + if(m_VerticalPageBreaks != nullptr) + proc.mandatory(*m_VerticalPageBreaks); + return true; +} int GLOBALS::serialize_calcPr(std::wostream & stream) { if (!m_CalcMode) return 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.h index 0173e493aa..6a8816655e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.h @@ -46,6 +46,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent (BinProcessor& proc); + virtual const bool saveContent (BinProcessor& proc); static const ElementType type = typeGLOBALS; From 66b56360dae54e97ae16bc0a04d9407d3f2abb12 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 25 Mar 2025 14:47:44 +0600 Subject: [PATCH 004/114] Add BOF writing --- .../XlsFile/Format/Logic/Biff_records/BOF.cpp | 23 +++++++++++++++++++ .../XlsFile/Format/Logic/Biff_records/BOF.h | 7 +++--- .../Format/Logic/Biff_records/Index.cpp | 11 +++++++++ .../XlsFile/Format/Logic/Biff_records/Index.h | 7 +++--- .../Format/Logic/Biff_records/Uncalced.cpp | 5 ++++ .../Format/Logic/Biff_records/Uncalced.h | 1 + .../Logic/Biff_structures/FilePointer.cpp | 4 ++++ .../Logic/Biff_structures/FilePointer.h | 3 ++- 8 files changed, 54 insertions(+), 7 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp index e7066f62b1..eb09f9f294 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp @@ -132,6 +132,29 @@ void BOF::readFields(CFRecord& record) } } +void BOF::writeFields(CFRecord& record) +{ + record << vers << dt << rupBuild << rupYear; + _UINT32 flags = 0; + + SETBIT(flags, 0, fWin); + SETBIT(flags, 1, fRisc); + SETBIT(flags, 2, fBeta); + SETBIT(flags, 3, fWinAny); + SETBIT(flags, 4, fMacAny); + SETBIT(flags, 5, fBetaAny); + SETBIT(flags, 8, fRiscAny); + SETBIT(flags, 9, fOOM); + SETBIT(flags, 10, fGlJmp); + SETBIT(flags, 13, fFontLimit); + + SETBITS(flags, 14, 17, verXLHigh); + + record << flags; + record << verLowestBiff << verLastXLSaved; + record.reserveNunBytes(2);// reserved +} + unsigned short BOF::getSubstreamType() { return dt; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.h index 89e4cee93a..a3c9a54057 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.h @@ -49,6 +49,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeBOF; @@ -87,9 +88,9 @@ public: bool fGlJmp; bool fFontLimit; - _UINT16 verXLHigh; - unsigned char verLowestBiff; - unsigned char verLastXLSaved; + _UINT16 verXLHigh = 0; + unsigned char verLowestBiff = 0; + unsigned char verLastXLSaved = 0; _CP_OPT(unsigned int) stream_ptr; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Index.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Index.cpp index 651bfafd21..3b1ef86118 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Index.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Index.cpp @@ -63,5 +63,16 @@ void Index::readFields(CFRecord& record) } } +void Index::writeFields(CFRecord& record) +{ + record.reserveNunBytes(4); // reserved + record << rwMic << rwMac << ibXF; + + for(auto i:rgibRw) + { + record << *i; + } +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Index.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Index.h index 59d9ce6dbb..8f7ae22d73 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Index.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Index.h @@ -48,13 +48,14 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeIndex; //----------------------------- - _UINT32 rwMic; - _UINT32 rwMac; - _UINT32 ibXF; + _UINT32 rwMic = 0; + _UINT32 rwMac = 0; + _UINT32 ibXF = 0; BiffStructurePtrVector rgibRw; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Uncalced.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Uncalced.cpp index d57bc183e0..da071e409a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Uncalced.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Uncalced.cpp @@ -55,5 +55,10 @@ void Uncalced::readFields(CFRecord& record) record.skipNunBytes(2); // reserved } +void Uncalced::writeFields(CFRecord& record) +{ + record.reserveNunBytes(2); // reserved +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Uncalced.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Uncalced.h index 5c0d41de1c..426499ef18 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Uncalced.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Uncalced.h @@ -49,6 +49,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeUncalced; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FilePointer.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FilePointer.cpp index 1467f4386f..d50ecb14cc 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FilePointer.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FilePointer.cpp @@ -57,6 +57,10 @@ void FilePointer::load(CFRecord& record) record >> offset; } +void FilePointer::save(CFRecord& record) +{ + record << offset; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FilePointer.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FilePointer.h index 712f507755..c72f72f860 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FilePointer.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FilePointer.h @@ -50,9 +50,10 @@ public: static const ElementType type = typeFilePointer; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); - _UINT32 offset; + _UINT32 offset = 0; }; typedef boost::shared_ptr FilePointerPtr; From 3ad2fff67b479214356edb31821598c16a801cd7 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 25 Mar 2025 15:53:51 +0600 Subject: [PATCH 005/114] Add page setup binary writing --- .../XlsFile/Format/Logic/Biff_records/Footer.cpp | 5 +++++ .../XlsFile/Format/Logic/Biff_records/Footer.h | 1 + .../XlsFile/Format/Logic/Biff_records/HCenter.cpp | 5 +++++ .../XlsFile/Format/Logic/Biff_records/HCenter.h | 3 ++- .../XlsFile/Format/Logic/Biff_records/Header.cpp | 5 +++++ .../XlsFile/Format/Logic/Biff_records/Header.h | 1 + .../XlsFile/Format/Logic/Biff_records/VCenter.cpp | 5 +++++ .../XlsFile/Format/Logic/Biff_records/VCenter.h | 3 ++- .../Format/Logic/Biff_unions/PAGESETUP.cpp | 15 +++++++++++++++ .../XlsFile/Format/Logic/Biff_unions/PAGESETUP.h | 1 + 10 files changed, 42 insertions(+), 2 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.cpp index 579288793f..e8add7e57d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.cpp @@ -68,5 +68,10 @@ void Footer::readFields(CFRecord& record) } } +void Footer::writeFields(CFRecord& record) +{ + record << ast; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.h index 8555d3e0c3..47967e0803 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.h @@ -51,6 +51,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeFooter; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HCenter.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HCenter.cpp index 9c211451c7..2576819cb4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HCenter.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HCenter.cpp @@ -55,5 +55,10 @@ void HCenter::readFields(CFRecord& record) record >> hcenter; } +void HCenter::writeFields(CFRecord& record) +{ + record << hcenter; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HCenter.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HCenter.h index 4962e97bf3..1bb816cc84 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HCenter.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HCenter.h @@ -47,11 +47,12 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeHCenter; //----------------------------- - Boolean hcenter; + Boolean hcenter = 0; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.cpp index 0458e8262c..b497a9d083 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.cpp @@ -68,5 +68,10 @@ void Header::readFields(CFRecord& record) } } +void Header::writeFields(CFRecord& record) +{ + record << ast; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.h index f33103812c..d854d7bf5e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.h @@ -51,6 +51,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeHeader; //----------------------------- diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VCenter.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VCenter.cpp index d45842d8d2..937d2feed9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VCenter.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VCenter.cpp @@ -53,5 +53,10 @@ void VCenter::readFields(CFRecord& record) record >> vcenter; } +void VCenter::writeFields(CFRecord& record) +{ + record << vcenter; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VCenter.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VCenter.h index 25bf2114f7..b4798d65a6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VCenter.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/VCenter.h @@ -47,11 +47,12 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeVCenter; //----------------------------- - Boolean vcenter; + Boolean vcenter = 0; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp index 137c71b9f1..3559c041ec 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp @@ -168,6 +168,21 @@ namespace XLS return true; } +const bool PAGESETUP::saveContent(BinProcessor& proc) +{ + if(m_Header != nullptr) + proc.mandatory(*m_Header); + if(m_Footer != nullptr) + proc.mandatory(*m_Footer); + if(m_HCenter != nullptr) + proc.mandatory(*m_HCenter); + if(m_VCenter != nullptr) + proc.mandatory(*m_VCenter); + if(m_Setup != nullptr) + proc.mandatory(*m_Setup); + return true; +} + int PAGESETUP::serialize(std::wostream & stream) { if (elements_.empty() && !m_Setup && !m_Header && !m_Footer) return 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.h index 52f07c78d3..61f1e96a5e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.h @@ -45,6 +45,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); int serialize(std::wostream & stream); From 7ad49a56504ee154e6a1bdd29c92de2751339dc4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 25 Mar 2025 18:14:24 +0600 Subject: [PATCH 006/114] Add headerFooter & columns writing --- .../Format/Logic/Biff_records/ColInfo.h | 6 ++-- .../Format/Logic/Biff_records/DefColWidth.cpp | 5 +++ .../Format/Logic/Biff_records/DefColWidth.h | 3 +- .../Logic/Biff_records/HeaderFooter.cpp | 34 +++++++++++++++++++ .../Format/Logic/Biff_records/HeaderFooter.h | 19 ++++++----- .../Format/Logic/Biff_unions/COLUMNS.cpp | 15 +++++++- .../Format/Logic/Biff_unions/COLUMNS.h | 1 + 7 files changed, 69 insertions(+), 14 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ColInfo.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ColInfo.h index c7f2629c50..6afc80ecfd 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ColInfo.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ColInfo.h @@ -51,9 +51,9 @@ public: static const ElementType type = typeColInfo; //----------------------------- - _UINT32 colFirst; - _UINT32 colLast; - _UINT32 coldx; + _UINT32 colFirst = 0; + _UINT32 colLast = 0; + _UINT32 coldx = 0; IXFCell ixfe = 0xffff; _UINT32 ixfeXLSB = 0xffffffff; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefColWidth.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefColWidth.cpp index f35385bea4..2a9307ad35 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefColWidth.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefColWidth.cpp @@ -61,5 +61,10 @@ void DefColWidth::readFields(CFRecord& record) } } +void DefColWidth::writeFields(CFRecord& record) +{ + record << cchdefColWidth; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefColWidth.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefColWidth.h index c7a6c1be35..007ccbc72e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefColWidth.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefColWidth.h @@ -50,11 +50,12 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeDefColWidth; //----------------------------- - _UINT16 cchdefColWidth; + _UINT16 cchdefColWidth = 8; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HeaderFooter.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HeaderFooter.cpp index c116cf4d6f..d7e06e3a5c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HeaderFooter.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HeaderFooter.cpp @@ -80,5 +80,39 @@ void HeaderFooter::readFields(CFRecord& record) } } +void HeaderFooter::writeFields(CFRecord& record) +{ + FrtHeader frtHeader(rt_HeaderFooter); + frtHeader.grbitFrt.fFrtRef = 0; + frtHeader.grbitFrt.fFrtAlert = 0; + record << frtHeader; + _GUID_ guid_num(0, 0, 0, 0); + record << guid_num; + _UINT16 flags = 0; + SETBIT(flags, 0, fHFDiffOddEven); + SETBIT(flags, 1, fHFDiffFirst); + SETBIT(flags, 2, fHFScaleWithDoc); + SETBIT(flags, 3, fHFAlignMargins); + record << flags; + record << cchHeaderEven << cchFooterEven << cchHeaderFirst << cchFooterFirst; + if(cchHeaderEven && strHeaderEven.getSize()) + { + record << strHeaderEven; + } + if(cchFooterEven && strFooterEven.getSize()) + { + record << strFooterEven; + } + if(cchHeaderFirst && strHeaderFirst.getSize()) + { + record << strHeaderFirst; + } + if(cchFooterFirst && strFooterFirst.getSize()) + { + record << strFooterFirst; + } + +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HeaderFooter.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HeaderFooter.h index 1bf82510f9..69437d2b53 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HeaderFooter.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HeaderFooter.h @@ -47,21 +47,22 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeHeaderFooter; //----------------------------- - std::wstring guidSView; + std::wstring guidSView = L""; - bool fHFDiffOddEven; - bool fHFDiffFirst; - bool fHFScaleWithDoc; - bool fHFAlignMargins; + bool fHFDiffOddEven = false; + bool fHFDiffFirst = false; + bool fHFScaleWithDoc = false; + bool fHFAlignMargins = false; - _UINT16 cchHeaderEven; - _UINT16 cchFooterEven; - _UINT16 cchHeaderFirst; - _UINT16 cchFooterFirst; + _UINT16 cchHeaderEven = 0; + _UINT16 cchFooterEven = 0; + _UINT16 cchHeaderFirst = 0; + _UINT16 cchFooterFirst = 0; XLUnicodeString strHeaderEven; XLUnicodeString strFooterEven; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp index 744f0a0a6e..f8a2d58d55 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp @@ -92,7 +92,20 @@ const bool COLUMNS::loadContent(BinProcessor& proc) return def_ok || (count > 0); } - +const bool COLUMNS::saveContent(BinProcessor& proc) +{ + global_info_ = proc.getGlobalWorkbookInfo(); + proc.mandatory(*m_DefColWidth); + for(auto i:global_info_->sheets_info[global_info_->current_sheet - 1].customColumnsWidth) + { + ColInfo column_info; + column_info.colFirst = i.first; + column_info.colLast = i.first; + column_info.coldx = i.second * 256; + proc.mandatory(column_info); + } + return true; +} int COLUMNS::serialize(std::wostream & stream) { if (elements_.size() < 1) return 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.h index 4a3cbcd532..b64620d6f1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.h @@ -46,6 +46,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); int serialize(std::wostream & stream); From f535cef848fbab5ebdca57f58d8e3a0cbd813bfa Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 25 Mar 2025 20:20:00 +0600 Subject: [PATCH 007/114] Add dimensions writing --- .../XlsFile/Format/Logic/Biff_records/Dimensions.cpp | 7 +++++++ .../XlsFile/Format/Logic/Biff_records/Dimensions.h | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.cpp index ef9ec1d4b4..38917528b9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.cpp @@ -81,6 +81,13 @@ void Dimensions::readFields(CFRecord& record) } } +void Dimensions::writeFields(CFRecord& record) +{ + record << rwMic << rwMac; + record << colMic << colMac; + record.reserveNunBytes(2); // reserved +} + int Dimensions::serialize(std::wostream & stream) { if (ref_.empty()) return 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h index a853a22848..9c0f251a78 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h @@ -47,17 +47,18 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeDimensions; int serialize(std::wostream & stream); - std::wstring ref_; + std::wstring ref_ = L""; //----------------------------- - _UINT32 rwMic; - _UINT32 rwMac; - _UINT16 colMic; - _UINT16 colMac; + _UINT32 rwMic = 0; + _UINT32 rwMac = 0; + _UINT16 colMic = 0; + _UINT16 colMac = 0; }; From 1d27cc61f4af812cdba47dc359efe2b373c3f35b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 26 Mar 2025 16:24:26 +0600 Subject: [PATCH 008/114] Add simple cells writing --- MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.cpp | 5 +++++ MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.h | 1 + .../XlsFile/Format/Logic/Biff_records/BoolErr.cpp | 5 +++++ MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.h | 1 + .../XlsFile/Format/Logic/Biff_records/LabelSst.cpp | 5 +++++ MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.h | 3 ++- .../XlsFile/Format/Logic/Biff_records/MulBlank.cpp | 8 +++++++- MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulBlank.h | 1 + MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.cpp | 8 ++++++++ MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.h | 1 + MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp | 6 ++++++ MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.h | 2 ++ MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.cpp | 7 +++++++ MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.h | 1 + MsBinaryFile/XlsFile/Format/Logic/Biff_records/Row.h | 8 ++++---- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.cpp | 5 +++++ MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.h | 5 +++-- .../XlsFile/Format/Logic/Biff_structures/Cell.cpp | 5 ++++- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.h | 7 ++++--- .../XlsFile/Format/Logic/Biff_structures/RkRec.cpp | 5 ++++- MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.h | 1 + 21 files changed, 77 insertions(+), 13 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.cpp index ac27672c7a..682f20d13d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.cpp @@ -58,6 +58,11 @@ void Blank::readFields(CFRecord& record) record >> cell; } +void Blank::writeFields(CFRecord& record) +{ + record << cell; +} + const CellRef Blank::getLocation() const { return cell.getLocation(); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.h index f0af35ec0b..30d3861a7d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Blank.h @@ -48,6 +48,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeBlank; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.cpp index 30690a23e9..b29f16e5a3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.cpp @@ -56,6 +56,11 @@ void BoolErr::readFields(CFRecord& record) record >> cell >> bes; } +void BoolErr::writeFields(CFRecord& record) +{ + record << cell << bes; +} + const CellRef BoolErr::getLocation() const { return cell.getLocation(); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.h index 9f78fb9669..2b2165deec 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.h @@ -53,6 +53,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeBoolErr; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.cpp index 29ae2e636f..0ee75214ad 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.cpp @@ -54,6 +54,11 @@ void LabelSst::readFields(CFRecord& record) record >> cell >> isst; } +void LabelSst::writeFields(CFRecord& record) +{ + record << cell << isst; +} + const CellRef LabelSst::getLocation() const { return cell.getLocation(); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.h index b1dc9742d3..02f01be8e3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.h @@ -49,6 +49,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); int serialize(std::wostream & stream); @@ -59,7 +60,7 @@ public: CellOffsetResender resender; Cell cell; - _UINT32 isst; + _UINT32 isst = 0; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulBlank.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulBlank.cpp index a9823b3d5d..c35ff468c4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulBlank.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulBlank.cpp @@ -97,7 +97,13 @@ void MulBlank::readFields(CFRecord& record) record.skipNunBytes(sizeof(unsigned short)); } - +void MulBlank::writeFields(CFRecord& record) +{ + record << rw << colFirst; + for(auto i:rgixfe.rgixfe) + record << i; + record << colLast; +} const int MulBlank::GetRow() const { return static_cast(rw); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulBlank.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulBlank.h index 29dd9c1a48..d068224ce7 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulBlank.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulBlank.h @@ -64,6 +64,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); const int GetRow() const; const int GetColumn() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.cpp index a14280fa8c..9b475e9902 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.cpp @@ -68,6 +68,14 @@ void MulRk::readFields(CFRecord& record) record.skipNunBytes(sizeof(unsigned short)); } +void MulRk::writeFields(CFRecord& record) +{ + record << rw << colFirst; + for(auto i:rgrkrec) + record << i; + record << colLast; +} + const int MulRk::GetRow() const { return static_cast(rw); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.h index ab675f5e3b..99d27027a1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MulRk.h @@ -49,6 +49,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); const int GetRow() const; const int GetColumn() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp index 5c25ca8a63..24d84775f8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp @@ -80,6 +80,12 @@ void Number::readFields(CFRecord& record) record >> val; } } + +void Number::writeFields(CFRecord& record) +{ + record << cell << num; +} + const CellRef Number::getLocation() const { return cell.getLocation(); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.h index 739e27de6e..e39d43e709 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.h @@ -50,6 +50,8 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); + static const ElementType type = typeNumber; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.cpp index 27f0dd55a8..11a8abb859 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.cpp @@ -61,6 +61,13 @@ void RK::readFields(CFRecord& record) cell = Cell(rw, col, rkrec.get_ixfe()); } +void RK::writeFields(CFRecord& record) +{ + Rw rw = cell.rw; + Col col = cell.col; + + record << rw << col << rkrec; +} const CellRef RK::getLocation() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.h index 62c9cbe28f..4ea0977cf3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.h @@ -49,6 +49,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeRK; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Row.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Row.h index edbcfa17c1..09d5a83a87 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Row.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Row.h @@ -53,10 +53,10 @@ namespace XLS static const ElementType type = typeRow; - UncheckedRw rw; - unsigned short colMic; - unsigned short colMac; - _UINT16 miyRw; + UncheckedRw rw = 0; + unsigned short colMic = 0; + unsigned short colMac = 0; + _UINT16 miyRw = 0; unsigned char iOutLevel = 0; bool fCollapsed = false; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.cpp index 1dfa2bee1f..67fcbaa2b1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.cpp @@ -49,6 +49,11 @@ void Bes::load(CFRecord& record) record >> bBoolErr >> fError; } +void Bes::save(CFRecord& record) +{ + record << bBoolErr << fError; +} + const std::wstring Bes::toString() { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.h index dfc85527b8..a792d0043b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Bes.h @@ -46,12 +46,13 @@ public: static const ElementType type = typeBes; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); const std::wstring toString(); void fromString(const std::wstring str); - unsigned char bBoolErr; - Boolean fError; + unsigned char bBoolErr = 0; + Boolean fError = 0; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp index b4cff4fc91..024c301d11 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp @@ -85,7 +85,10 @@ void Cell::load(CFRecord& record) record >> ixfe; } } - +void Cell::save(CFRecord& record) +{ + record << rw << col << ixfe; +} const CellRef Cell::getLocation() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.h index 1e23673577..409f9e5245 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.h @@ -50,14 +50,15 @@ public: BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); const CellRef getLocation() const; static const ElementType type = typeCell; - Rw rw; - Col col; - IXFCell ixfe; + Rw rw = 0; + Col col = 0; + IXFCell ixfe = 0; }; typedef boost::shared_ptr CellPtr; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.cpp index d646996f70..08b30a5b72 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.cpp @@ -47,7 +47,10 @@ void RkRec::load(CFRecord& record) record >> ixfe >> RK_; } - +void RkRec::save(CFRecord& record) +{ + record << ixfe << RK_; +} const unsigned short RkRec::get_ixfe() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.h index 0c65b89825..6b62cf9850 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.h @@ -46,6 +46,7 @@ public: BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); static const ElementType type = typeRkRec; From 87f0835010db6a281444ecae3e32811312aac485 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 28 Mar 2025 17:00:25 +0600 Subject: [PATCH 009/114] Add formula writing --- .../Format/Logic/Biff_records/Continue.cpp | 5 ++ .../Format/Logic/Biff_records/Continue.h | 5 +- .../Format/Logic/Biff_records/Formula.cpp | 12 +++++ .../Format/Logic/Biff_records/Formula.h | 1 + .../Format/Logic/Biff_records/String.cpp | 5 ++ .../Format/Logic/Biff_records/String.h | 1 + .../Logic/Biff_structures/FormulaValue.cpp | 4 ++ .../Logic/Biff_structures/FormulaValue.h | 1 + .../Format/Logic/Biff_unions/FORMULA.h | 4 ++ .../Format/Logic/Biff_unions/FORMULA_bu.cpp | 48 +++++++++++++++++++ 10 files changed, 84 insertions(+), 2 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Continue.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Continue.cpp index 52f5734f41..70668d5a17 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Continue.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Continue.cpp @@ -78,5 +78,10 @@ void Continue::readFields(CFRecord& record) record.skipNunBytes(m_iDataSize); } +void Continue::writeFields(CFRecord& record) +{ + record.appendRawDataToStatic(reinterpret_cast(m_pData), m_iDataSize); +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Continue.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Continue.h index a6fb08a212..57fe62aeb7 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Continue.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Continue.h @@ -47,11 +47,12 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeContinue; - char* m_pData; - int m_iDataSize; + char* m_pData = NULL; + int m_iDataSize = 0; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.cpp index 351d22e0be..71fc9c79f5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.cpp @@ -73,6 +73,18 @@ void Formula::readFields(CFRecord& record) formula.load(record); } +void Formula::writeFields(CFRecord& record) +{ + unsigned short flags = 0; + SETBIT(flags, 0, fAlwaysCalc); + SETBIT(flags, 2, fFill); + SETBIT(flags, 3, fShrFmla); + SETBIT(flags, 5, fClearErrors); + record << cell << val << flags; + record.reserveNunBytes(4); + formula.save(record); +} + const CellRef Formula::getLocation() const { return cell.getLocation(); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.h index 7f92b5b1df..f0fac92ccc 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.h @@ -49,6 +49,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeFormula; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/String.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/String.cpp index d6ed3985c4..f5a1bb7dd6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/String.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/String.cpp @@ -71,5 +71,10 @@ void String::readFields(CFRecord& record) } } +void String::writeFields(CFRecord& record) +{ + record << string; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/String.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/String.h index 674d250ec8..4fc4851ff3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/String.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/String.h @@ -48,6 +48,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeString; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FormulaValue.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FormulaValue.cpp index 1a31090779..f389392e2c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FormulaValue.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FormulaValue.cpp @@ -82,6 +82,10 @@ void FormulaValue::load(CFRecord& record) record >> data.xnum; } +void FormulaValue::save(CFRecord& record) +{ + record << data.xnum; +} unsigned char FormulaValue::getType() { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FormulaValue.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FormulaValue.h index 8696f2c2db..f4fd38661b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FormulaValue.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FormulaValue.h @@ -45,6 +45,7 @@ public: BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); static const ElementType type = typeFormulaValue; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA.h index c5766e8084..7974186e95 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA.h @@ -34,6 +34,8 @@ #include "../CompositeObject.h" #include "../Biff_structures/CellRef.h" #include "../Biff_structures/CellRangeRef.h" +#include "../Biff_structures/BiffString.h" +#include "../Base/Nullable.h" namespace XLS { @@ -51,6 +53,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); static const ElementType type = typeFORMULA; int serialize(std::wostream & stream); @@ -64,6 +67,7 @@ public: BaseObjectPtr m_Cash; std::vector m_arContinue; + nullable m_stringValCache; CellRef location; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA_bu.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA_bu.cpp index 0f53b5af38..655678055e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA_bu.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA_bu.cpp @@ -147,6 +147,54 @@ const bool FORMULA::loadContent(BinProcessor& proc) return true; } +const bool FORMULA::saveContent(BinProcessor& proc) +{ + if(m_Formula != nullptr) + proc.mandatory(*m_Formula); + if(m_ArrayFormula != nullptr) + proc.mandatory(*m_ArrayFormula); + else if (m_TableFormula != nullptr) + proc.mandatory(*m_TableFormula); + else if (m_SharedFormula != nullptr) + proc.mandatory(*m_SharedFormula); + if(m_stringValCache.IsInit()) + { + String strVal; + _UINT32 maxRecordSize = 4112; + auto cachePtr = m_stringValCache.GetPointer(); + if(cachePtr->getSize() <= maxRecordSize) + { + strVal.string = *cachePtr; + proc.mandatory(strVal); + } + else + { + auto tempVal = cachePtr->value(); + strVal.string = tempVal.substr(0, maxRecordSize); + proc.mandatory(strVal); + tempVal.erase(0, maxRecordSize); + while(tempVal.size() > 0) + { + size_t bytesSize = 0; + if(tempVal.size() > maxRecordSize) + bytesSize = sizeof(wchar_t) * maxRecordSize; + else + bytesSize = sizeof(wchar_t) * tempVal.size(); + Continue continueRecord; + continueRecord.m_pData = new char[bytesSize * 2]; + continueRecord.m_iDataSize = bytesSize * 2; + memcpy(continueRecord.m_pData, tempVal.data() ,bytesSize * 2); + proc.mandatory(continueRecord); + if(tempVal.size() > bytesSize) + tempVal.erase(0, bytesSize); + else + break; + } + } + } + return true; +} + const CellRef FORMULA::getLocation() const { return location; From 61640a9a060e15bbf1acbb6bf83c60face1ad8dd Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 28 Mar 2025 19:13:13 +0600 Subject: [PATCH 010/114] Add celltable writing --- .../Format/Logic/Biff_records/DBCell.cpp | 8 + .../Format/Logic/Biff_records/DBCell.h | 1 + .../Logic/Biff_structures/FileOffset.cpp | 5 + .../Format/Logic/Biff_structures/FileOffset.h | 1 + .../XlsFile/Format/Logic/Biff_unions/CELL.h | 3 + .../Format/Logic/Biff_unions/CELLTABLE.cpp | 220 +++++++++--------- .../Format/Logic/Biff_unions/CELLTABLE.h | 35 +++ .../Format/Logic/Biff_unions/CELL_bu.cpp | 9 + 8 files changed, 171 insertions(+), 111 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.cpp index 83cd14faf5..5a32bd50d8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.cpp @@ -60,6 +60,14 @@ void DBCell::readFields(CFRecord& record) rgdb.push_back(element); } } +void DBCell::writeFields(CFRecord& record) +{ + record << dbRtrw; + for(auto i : rgdb) + { + record << i; + } +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.h index 41b276cf9a..5d33b4e8ab 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.h @@ -50,6 +50,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeDBCell; //----------------------------- diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.cpp index ea61a49ff8..944c7adb03 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.cpp @@ -47,6 +47,11 @@ void FileOffset::load(CFRecord& record) record >> offset; } +void FileOffset::save(CFRecord& record) +{ + record << offset; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.h index 01f572a3e9..7cf73c47d7 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.h @@ -47,6 +47,7 @@ public: static const ElementType type = typeFileOffset; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); unsigned short offset; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL.h index 6d9ebbf67a..5888c4f862 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL.h @@ -48,6 +48,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); int serialize(std::wostream & stream); @@ -56,6 +57,8 @@ public: int RowNumber; int ColumnNumber; + BaseObjectPtr cellContent; // for xls writing + std::vector& shared_formulas_locations_ref_; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp index d13a880414..4cf54485f0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp @@ -42,133 +42,121 @@ namespace XLS { -class CELL_GROUP : public CompositeObject + +const bool CELL_GROUP::loadContent(BinProcessor& proc) { - BASE_OBJECT_DEFINE_CLASS_NAME(CELL_GROUP) -public: - CELL_GROUP(std::vector& shared_formulas_locations_ref) : - shared_formulas_locations_ref_(shared_formulas_locations_ref) - { - } + global_info_ = proc.getGlobalWorkbookInfo(); + int index_sheet_info_ = global_info_->current_sheet - 1; - BaseObjectPtr clone() - { - return BaseObjectPtr(new CELL_GROUP(*this)); - } + GlobalWorkbookInfo::_sheet_info & sheet_info = global_info_->sheets_info[index_sheet_info_]; - const bool loadContent(BinProcessor& proc) - { - global_info_ = proc.getGlobalWorkbookInfo(); - int index_sheet_info_ = global_info_->current_sheet - 1; + int count, count_row = 0; - GlobalWorkbookInfo::_sheet_info & sheet_info = global_info_->sheets_info[index_sheet_info_]; - - int count, count_row = 0; - - bool bRow = false; + bool bRow = false; - bRow = (global_info_->Version == 0x0200) ? proc.mandatory() : proc.mandatory(); - - if (bRow == true) - { - count_row = count = 1 + ((global_info_->Version == 0x0200) ? proc.repeated(0, 0) : proc.repeated(0, 0)); - - while(count > 0) - { - Row* row = dynamic_cast(elements_.front().get()); - if (row) - { - if (row->miyRw > 0 && std::abs(row->miyRw/20. - sheet_info.defaultRowHeight) > 0.001) - { - sheet_info.customRowsHeight.insert(std::make_pair(row->rw, row->miyRw / 20.)); - } - } - std::map::iterator pFindRow = sheet_info.mapRows.find(row->rw); - if (pFindRow == sheet_info.mapRows.end()) - { - GlobalWorkbookInfo::_row_info row_info; + bRow = (global_info_->Version == 0x0200) ? proc.mandatory() : proc.mandatory(); - row_info.row_info = elements_.front(); - sheet_info.mapRows.insert(std::make_pair(row->rw, row_info)); - } - else - { - if (!pFindRow->second.row_info) - { - pFindRow->second.row_info = elements_.front(); - } - else - { - Row* row_find = dynamic_cast(pFindRow->second.row_info.get()); - if ((row_find) && (false == row_find->bValid) && row->bValid) - { - pFindRow->second.row_info = elements_.front(); - } + if (bRow == true) + { + count_row = count = 1 + ((global_info_->Version == 0x0200) ? proc.repeated(0, 0) : proc.repeated(0, 0)); - } - } + while(count > 0) + { + Row* row = dynamic_cast(elements_.front().get()); + if (row) + { + if (row->miyRw > 0 && std::abs(row->miyRw/20. - sheet_info.defaultRowHeight) > 0.001) + { + sheet_info.customRowsHeight.insert(std::make_pair(row->rw, row->miyRw / 20.)); + } + } + std::map::iterator pFindRow = sheet_info.mapRows.find(row->rw); + if (pFindRow == sheet_info.mapRows.end()) + { + GlobalWorkbookInfo::_row_info row_info; - elements_.pop_front(); - count--; - } - } - - //------------------------------------------------------------------------------------------------------------------ - CELL cell(shared_formulas_locations_ref_); + row_info.row_info = elements_.front(); + sheet_info.mapRows.insert(std::make_pair(row->rw, row_info)); + } + else + { + if (!pFindRow->second.row_info) + { + pFindRow->second.row_info = elements_.front(); + } + else + { + Row* row_find = dynamic_cast(pFindRow->second.row_info.get()); + if ((row_find) && (false == row_find->bValid) && row->bValid) + { + pFindRow->second.row_info = elements_.front(); + } - int count_cells = count = proc.repeated(cell, 0, 0); + } + } - while(count > 0) - { - CELL * cell = dynamic_cast(elements_.front().get()); - if (cell) - { - std::map::iterator pFindRow = sheet_info.mapRows.find(cell->RowNumber); - if (pFindRow == sheet_info.mapRows.end()) - { - GlobalWorkbookInfo::_row_info row_info; - sheet_info.mapRows.insert(std::make_pair(cell->RowNumber, row_info)); + elements_.pop_front(); + count--; + } + } - pFindRow = sheet_info.mapRows.find(cell->RowNumber); - } - std::map::iterator pFindCell = pFindRow->second.mapCells.find(cell->ColumnNumber); + //------------------------------------------------------------------------------------------------------------------ + CELL cell(shared_formulas_locations_ref_); - if (pFindCell != pFindRow->second.mapCells.end()) - { - CELL* cell_prev = dynamic_cast(pFindCell->second.get()); + int count_cells = count = proc.repeated(cell, 0, 0); - pFindCell->second = elements_.front(); - } - else - { - pFindRow->second.mapCells.insert(std::make_pair(cell->ColumnNumber, elements_.front())); - } - } - elements_.pop_front(); - count--; - } - count = proc.repeated(0, 0); - // OpenOffice Calc stored files workaround (DBCell must be present at least once according to [MS-XLS]) - while(count > 0) - { - m_DBCells.insert(m_DBCells.begin(), elements_.back()); - elements_.pop_back(); - count--; - } - if (count_cells > 0 || count_row > 0) return true; - else return false; - } - - static const ElementType type = typeCELL_GROUP; + while(count > 0) + { + CELL * cell = dynamic_cast(elements_.front().get()); + if (cell) + { + std::map::iterator pFindRow = sheet_info.mapRows.find(cell->RowNumber); + if (pFindRow == sheet_info.mapRows.end()) + { + GlobalWorkbookInfo::_row_info row_info; + sheet_info.mapRows.insert(std::make_pair(cell->RowNumber, row_info)); -//--------------------------------------------------------------------------- - std::list m_DBCells; + pFindRow = sheet_info.mapRows.find(cell->RowNumber); + } + std::map::iterator pFindCell = pFindRow->second.mapCells.find(cell->ColumnNumber); -private: - std::vector& shared_formulas_locations_ref_; + if (pFindCell != pFindRow->second.mapCells.end()) + { + CELL* cell_prev = dynamic_cast(pFindCell->second.get()); - GlobalWorkbookInfoPtr global_info_; -}; + pFindCell->second = elements_.front(); + } + else + { + pFindRow->second.mapCells.insert(std::make_pair(cell->ColumnNumber, elements_.front())); + } + } + elements_.pop_front(); + count--; + } + count = proc.repeated(0, 0); + // OpenOffice Calc stored files workaround (DBCell must be present at least once according to [MS-XLS]) + while(count > 0) + { + m_DBCells.insert(m_DBCells.begin(), elements_.back()); + elements_.pop_back(); + count--; + } + if (count_cells > 0 || count_row > 0) return true; + else return false; +} +const bool CELL_GROUP::saveContent(BinProcessor& proc) +{ + if(m_row != nullptr) + proc.mandatory(*m_row); + for(auto i : m_arCells) + if(i != nullptr) + proc.mandatory(*i); + for(auto i : m_DBCells) + if(i != nullptr) + proc.mandatory(*i); + return true; +} //----------------------------------------------------------------------------------------------------------------- CELLTABLE::CELLTABLE(std::vector& shared_formulas_locations_ref) : isConcatinate_(false), shared_formulas_locations_ref_(shared_formulas_locations_ref) @@ -222,6 +210,16 @@ const bool CELLTABLE::loadContent(BinProcessor& proc) } return true; } + +const bool CELLTABLE::saveContent(BinProcessor& proc) +{ + for(auto i: m_arCellGroups) + if(i != nullptr) + proc.mandatory(*i); + return true; +} + + int CELLTABLE::serialize(std::wostream & stream) { GlobalWorkbookInfo::_sheet_info & sheet_info = global_info_->sheets_info[index_sheet_info_]; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h index 58383874e8..1c1a386c1a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h @@ -48,6 +48,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); static const ElementType type = typeCELLTABLE; @@ -57,10 +58,44 @@ public: std::vector m_arEntExU2; + std::vector m_arCellGroups; + GlobalWorkbookInfoPtr global_info_; int index_sheet_info_; bool isConcatinate_; }; +class CELL_GROUP : public CompositeObject +{ + BASE_OBJECT_DEFINE_CLASS_NAME(CELL_GROUP) +public: + CELL_GROUP(std::vector& shared_formulas_locations_ref) : + shared_formulas_locations_ref_(shared_formulas_locations_ref) + { + } + + BaseObjectPtr clone() + { + return BaseObjectPtr(new CELL_GROUP(*this)); + } + + const bool loadContent(BinProcessor& proc); + const bool saveContent(BinProcessor& proc); + + + static const ElementType type = typeCELL_GROUP; + +//--------------------------------------------------------------------------- + BaseObjectPtr m_row;//for xls writing + std::vector m_arCells; + + std::list m_DBCells; + +private: + std::vector& shared_formulas_locations_ref_; + + GlobalWorkbookInfoPtr global_info_; +}; + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL_bu.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL_bu.cpp index d3ca2fc2e3..3fd4644aae 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL_bu.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL_bu.cpp @@ -151,6 +151,15 @@ const bool CELL::loadContent(BinProcessor& proc) return true; } +const bool CELL::saveContent(BinProcessor& proc) +{ + if(cellContent != nullptr) + proc.mandatory(*cellContent); + else + return false; + return true; +} + int CELL::serialize(std::wostream & stream) { CP_XML_WRITER(stream) From 421f5bb0f297224875dfb418755089b0ec01c800 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 31 Mar 2025 15:43:12 +0600 Subject: [PATCH 011/114] Add window binary writing --- .../XlsFile/Format/Logic/Biff_records/PLV.cpp | 12 ++++++++++++ .../XlsFile/Format/Logic/Biff_records/PLV.h | 1 + .../XlsFile/Format/Logic/Biff_records/Scl.cpp | 6 ++++++ .../XlsFile/Format/Logic/Biff_records/Scl.h | 1 + .../Format/Logic/Biff_records/Window2.cpp | 1 + .../XlsFile/Format/Logic/Biff_unions/WINDOW.cpp | 16 ++++++++++++++++ .../XlsFile/Format/Logic/Biff_unions/WINDOW.h | 1 + 7 files changed, 38 insertions(+) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PLV.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PLV.cpp index 24fea82667..e2fd6717a1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PLV.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PLV.cpp @@ -62,5 +62,17 @@ void PLV::readFields(CFRecord& record) fWhitespaceHidden = GETBIT(flags, 2); } +void PLV::writeFields(CFRecord& record) +{ + FrtHeader frtHeader(rt_PLV); + record << frtHeader; + unsigned short flags = 0; + SETBIT(flags, 0, fPageLayoutView); + SETBIT(flags, 1, fRulerVisible); + SETBIT(flags, 2, fWhitespaceHidden); + record << wScalePLV << flags; + +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PLV.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PLV.h index 52449a4704..910df42568 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PLV.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/PLV.h @@ -50,6 +50,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typePLV; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Scl.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Scl.cpp index b96fc95db6..66762f54fe 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Scl.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Scl.cpp @@ -56,5 +56,11 @@ void Scl::readFields(CFRecord& record) //Fraction = static_cast(nscl) / static_cast(dscl); } +void Scl::writeFields(CFRecord& record) +{ + record << nscl << dscl; + //Fraction = static_cast(nscl) / static_cast(dscl); +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Scl.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Scl.h index c04ae2ec3e..966ed4df5e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Scl.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Scl.h @@ -50,6 +50,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeScl; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp index bc27878896..3428cc9ac6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.cpp @@ -202,6 +202,7 @@ void Window2::writeFields(CFRecord& record) record.reserveNunBytes(2); // reserved record << wScaleSLV << wScaleNormal; + record.reserveNunBytes(4); // must be ignored } else diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.cpp index 34d31cd459..bf3e72c7af 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.cpp @@ -94,6 +94,22 @@ const bool WINDOW::loadContent(BinProcessor& proc) return true; } +const bool WINDOW::saveContent(BinProcessor& proc) +{ + if(m_Window2 != nullptr) + proc.mandatory(*m_Window2); + if(m_PLV != nullptr) + proc.mandatory(*m_PLV); + if(m_Scl != nullptr) + proc.mandatory(*m_Scl); + if(m_Pane != nullptr) + proc.mandatory(*m_Pane); + for(auto i : m_arSelection) + if(i != nullptr) + proc.mandatory(*i); + return true; +} + int WINDOW::serialize(std::wostream & stream) { Window2 * window2 = dynamic_cast(m_Window2.get()); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.h index 719ab42a48..35d4e94226 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.h @@ -49,6 +49,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); int serialize(std::wostream & stream); From e76398db012331f0552f3ae695242861cbe42a9c Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 1 Apr 2025 21:08:05 +0600 Subject: [PATCH 012/114] Add cond fmt records writing --- .../XlsFile/Format/Logic/Biff_records/CF.cpp | 20 +++++++++++++++++++ .../XlsFile/Format/Logic/Biff_records/CF.h | 1 + .../Format/Logic/Biff_records/CFEx.cpp | 9 +++++++++ .../XlsFile/Format/Logic/Biff_records/CFEx.h | 1 + .../Format/Logic/Biff_records/CondFmt.cpp | 9 +++++++++ .../Format/Logic/Biff_records/CondFmt.h | 1 + .../Logic/Biff_structures/CFExNonCF12.cpp | 17 ++++++++++++++++ .../Logic/Biff_structures/CFExNonCF12.h | 1 + .../Biff_structures/CFExTemplateParams.cpp | 5 +++++ .../Biff_structures/CFExTemplateParams.h | 1 + .../Biff_structures/CFParsedFormulaNoCCE.cpp | 4 ++++ .../Biff_structures/CFParsedFormulaNoCCE.h | 1 + .../Logic/Biff_structures/CellRangeRef.h | 16 +++++++-------- .../Biff_structures/CondFmtStructure.cpp | 11 ++++++++++ .../Logic/Biff_structures/CondFmtStructure.h | 1 + .../Logic/Biff_structures/FrtRefHeader.cpp | 6 ++++++ .../Logic/Biff_structures/FrtRefHeader.h | 1 + .../Format/Logic/Biff_unions/CONDFMT.h | 1 + .../Format/Logic/Biff_unions/CONDFMT_bu.cpp | 10 ++++++++++ 19 files changed, 108 insertions(+), 8 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.cpp index 4350f27591..3e16578c3c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.cpp @@ -79,6 +79,26 @@ void CF::readFields(CFRecord& record) dxfId_ = global_info_->RegistrDxfn(strm.str()); } +void CF::writeFields(CFRecord& record) +{ + record << ct << cp; + record.reserveNunBytes(4); + auto ccePos = record.getRdPtr(); + rgce1.save(record); + unsigned short rgceSize = record.getRdPtr() - ccePos; + record.RollRdPtrBack(rgceSize + 4); + record << rgceSize; + record.skipNunBytes(rgceSize + 2); + + auto rgce2pos = record.getRdPtr(); + rgce2.save(record); + rgceSize = record.getRdPtr() - rgce2pos; + record.RollRdPtrBack((record.getRdPtr() - ccePos) + 2); + record << rgceSize; + record.skipNunBytes(rgce2pos+ rgceSize); + +} + int CF::serialize(std::wostream & stream) { if (ct != 1 && ct != 2 && ct !=6) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.h index 777ca01f57..d299843ac2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.h @@ -49,6 +49,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCF; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CFEx.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CFEx.cpp index a6208b6c8b..b26d3a8161 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CFEx.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CFEx.cpp @@ -68,5 +68,14 @@ void CFEx::readFields(CFRecord& record) } } +void CFEx::writeFields(CFRecord& record) +{ + record << frtRefHeaderU << fIsCF12 << nID; + if(!fIsCF12) + { + record << content; + } +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CFEx.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CFEx.h index 19ea15863e..e8b0105d53 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CFEx.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CFEx.h @@ -49,6 +49,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCFEx; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt.cpp index 2fe269081b..36d667b080 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt.cpp @@ -61,6 +61,15 @@ void CondFmt::readFields(CFRecord& record) refBound = static_cast(refBound_ref); } +void CondFmt::writeFields(CFRecord& record) +{ + unsigned short flags = 0; + record << ccf << flags; + SETBIT(flags, 0, fToughRecalc); + SETBITS(flags, 1, 15, nID); + Ref8U refBound_ref = refBound; + record << refBound_ref << sqref; +} const CellRef CondFmt::getLocation() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt.h index f13a34716c..17ec8cb628 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt.h @@ -47,6 +47,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCondFmt; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExNonCF12.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExNonCF12.cpp index 0787b14a67..8d5fc49fa9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExNonCF12.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExNonCF12.cpp @@ -60,6 +60,23 @@ void CFExNonCF12::load(CFRecord& record) record >> rgbTemplateParms; } +void CFExNonCF12::save(CFRecord& record) +{ + unsigned char flags = 0; + SETBIT(flags, 0, fActive); + SETBIT(flags, 1, fStopIfTrue); + record << icf << cp << icfTemplate << ipriority_ << flags; + + record << fHasDXF; + + if(fHasDXF) + { + record << dxf; + } + unsigned char cbTemplateParm = 16; + record << cbTemplateParm; + record << rgbTemplateParms; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExNonCF12.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExNonCF12.h index fa9e604498..3b0ba8a0c6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExNonCF12.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExNonCF12.h @@ -49,6 +49,7 @@ public: static const ElementType type = typeCFExNonCF12; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); unsigned short icf; unsigned char cp; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExTemplateParams.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExTemplateParams.cpp index abf20e5ab9..994bf62807 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExTemplateParams.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExTemplateParams.cpp @@ -47,5 +47,10 @@ void CFExTemplateParams::load(CFRecord& record) record.loadAnyData(data); } +void CFExTemplateParams::save(CFRecord& record) +{ + record.storeAnyData(data); +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExTemplateParams.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExTemplateParams.h index 7a1bd78f99..89720c40bb 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExTemplateParams.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFExTemplateParams.h @@ -110,6 +110,7 @@ public: BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); static const ElementType type = typeCFExTemplateParams; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormulaNoCCE.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormulaNoCCE.cpp index 716be327b5..ced27b39eb 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormulaNoCCE.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormulaNoCCE.cpp @@ -54,6 +54,10 @@ void CFParsedFormulaNoCCE::load(CFRecord& record, const unsigned short cce) rgce.load(record, cce); } +void CFParsedFormulaNoCCE::save(CFRecord& record) +{ + rgce.save(record); +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormulaNoCCE.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormulaNoCCE.h index 00a1149ecb..ab6f219181 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormulaNoCCE.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFParsedFormulaNoCCE.h @@ -43,6 +43,7 @@ public: CFParsedFormulaNoCCE(const CellRef& cell_base_ref_init); BiffStructurePtr clone(); void load(CFRecord& record, const unsigned short cce); + void save(CFRecord& record); private: // stub to make the class non-abstract diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h index 6c9fa24d27..0a3d49488e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.h @@ -83,14 +83,14 @@ public: void load(CFRecord& record) override {} void save(CFRecord& record) override {} - int rowFirst; - int rowLast; - bool rowFirstRelative; - bool rowLastRelative; - int columnFirst; - int columnLast; - bool columnFirstRelative; - bool columnLastRelative; + int rowFirst = 0; + int rowLast = 0; + bool rowFirstRelative = 0; + bool rowLastRelative = 0; + int columnFirst = 0; + int columnLast = 0; + bool columnFirstRelative = 0; + bool columnLastRelative = 0; mutable std::wstring to_string_cache; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.cpp index 9c04abb1ba..51eade23db 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.cpp @@ -52,6 +52,17 @@ void CondFmtStructure::load(CFRecord& record) record >> refBound >> sqref; } +void CondFmtStructure::save(CFRecord& record) +{ + record << ccf; + unsigned short flags = 0; + SETBIT(flags, 0, fToughRecalc); + SETBITS(flags, 1, 15, nID); + record << flags; + + record << refBound << sqref; +} + const CellRef CondFmtStructure::getLocation() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.h index 35bd3d7038..01d2f9c5c2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.h @@ -46,6 +46,7 @@ public: static const ElementType type = typeCondFmtStructure; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); const CellRef getLocation() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeader.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeader.cpp index 2a1d37b491..62033820f4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeader.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeader.cpp @@ -48,6 +48,12 @@ void FrtRefHeader::load(CFRecord& record) record >> ref8; } +void FrtRefHeader::save(CFRecord& record) +{ + record << rt << grbitFrt; + record << ref8; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeader.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeader.h index 94cfd1dfa0..8b40fb8f17 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeader.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeader.h @@ -50,6 +50,7 @@ public: static const ElementType type = typeFrtRefHeader; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); CFRecordType::TypeId rt; FrtFlags grbitFrt; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT.h index e20032a7c0..61907df5f2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT.h @@ -48,6 +48,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); static const ElementType type = typeCONDFMT; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT_bu.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT_bu.cpp index 3c9dc33f70..1c5c66bd0a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT_bu.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT_bu.cpp @@ -79,6 +79,16 @@ const bool CONDFMT::loadContent(BinProcessor& proc) return true; } + +const bool CONDFMT::saveContent(BinProcessor& proc) +{ + if(m_CondFmt != nullptr) + proc.mandatory(*m_CondFmt); + for(auto i : m_arCF) + if(i != nullptr) + proc.mandatory(*i); + return true; +} int CONDFMT::serialize(std::wostream & stream) { if (!m_CondFmt) return 0; From e5d6f5df471b0665cb292bbe056bc354ac3833e0 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 2 Apr 2025 16:41:21 +0600 Subject: [PATCH 013/114] Add dxfn struct writing --- .../Logic/Biff_structures/BitMarkedStructs.h | 4 +- .../Format/Logic/Biff_structures/DXFALC.cpp | 16 +++++ .../Format/Logic/Biff_structures/DXFALC.h | 22 +++--- .../Format/Logic/Biff_structures/DXFBdr.cpp | 25 +++++++ .../Format/Logic/Biff_structures/DXFBdr.h | 1 + .../Format/Logic/Biff_structures/DXFFntD.cpp | 20 ++++++ .../Format/Logic/Biff_structures/DXFFntD.h | 4 +- .../Format/Logic/Biff_structures/DXFN.cpp | 70 +++++++++++++++++++ .../Format/Logic/Biff_structures/DXFN.h | 1 + .../Format/Logic/Biff_structures/DXFNum.cpp | 11 +++ .../Format/Logic/Biff_structures/DXFNum.h | 1 + .../Logic/Biff_structures/DXFNumUsr.cpp | 11 +++ .../Format/Logic/Biff_structures/DXFNumUsr.h | 3 +- .../Format/Logic/Biff_structures/DXFPat.cpp | 12 ++++ .../Format/Logic/Biff_structures/DXFPat.h | 1 + .../Format/Logic/Biff_structures/DXFProt.cpp | 8 +++ .../Format/Logic/Biff_structures/DXFProt.h | 2 +- .../Format/Logic/Biff_structures/Stxp.cpp | 5 ++ .../Format/Logic/Biff_structures/Stxp.h | 2 + 19 files changed, 203 insertions(+), 16 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BitMarkedStructs.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BitMarkedStructs.h index 1b00497a7e..a505b0ba06 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BitMarkedStructs.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BitMarkedStructs.h @@ -258,9 +258,9 @@ private: struct DXFNumIFmt { private: - unsigned char unused; + unsigned char unused = 0; public: - unsigned char ifmt; + unsigned char ifmt = 0; }; struct FFErrorCheck diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFALC.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFALC.cpp index 176aecfbd3..78a5e7d624 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFALC.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFALC.cpp @@ -56,6 +56,22 @@ void DXFALC::load(CFRecord& record) record >> iIndent; } +void DXFALC::save(CFRecord& record) +{ + _UINT32 flags = 0; + SETBITS(flags, 0, 2, alc) + SETBIT(flags, 3, fWrap) + SETBITS(flags, 4, 6, alcv) + SETBIT(flags, 7, fJustLast) + SETBITS(flags, 8, 15, trot) + SETBITS(flags, 16, 19, cIndent) + SETBIT(flags, 20, fShrinkToFit) + SETBIT(flags, 21, fMergeCell) + SETBITS(flags, 22, 23, iReadingOrder) + + record << flags << iIndent; +} + int DXFALC::serialize(std::wostream & stream) { if (parent->iReadingOrderNinch && parent->alchNinch && parent->alcvNinch && parent->wrapNinch && diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFALC.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFALC.h index 6ed028f783..79597cd3f7 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFALC.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFALC.h @@ -48,21 +48,21 @@ public: static const ElementType type = typeDXFALC; virtual void load(CFRecord& record); - + virtual void save(CFRecord& record); int serialize(std::wostream & stream); - unsigned char alc; - bool fWrap; - unsigned char alcv; - bool fJustLast; - unsigned char trot; - unsigned char cIndent; - bool fShrinkToFit; - bool fMergeCell; - unsigned char iReadingOrder; + unsigned char alc = 0; + bool fWrap = 0; + unsigned char alcv = 0; + bool fJustLast = 0; + unsigned char trot = 0; + unsigned char cIndent = 0; + bool fShrinkToFit = 0; + bool fMergeCell = 0; + unsigned char iReadingOrder = 0; - _UINT32 iIndent; + _UINT32 iIndent = 0; //------------------------------------------------ DXFN *parent; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFBdr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFBdr.cpp index da6d200fa6..5a3335e0d1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFBdr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFBdr.cpp @@ -66,6 +66,31 @@ void DXFBdr::load(CFRecord& record) } +void DXFBdr::save(CFRecord& record) +{ + _UINT32 flags = 0; + SETBITS(flags, 0, 3, dgLeft) + SETBITS(flags, 4, 7, dgRight) + SETBITS(flags, 8, 11, dgTop) + SETBITS(flags, 12, 15, dgBottom) + + SETBITS(flags, 16, 22, icvLeft) + SETBITS(flags, 23, 29, icvRight) + + SETBIT(flags, 30, bitDiagDown); + SETBIT(flags, 31, bitDiagUp); + + record << flags; + flags = 0; + + SETBITS(flags, 0, 6, icvTop) + SETBITS(flags, 7, 13, icvBottom) + SETBITS(flags, 14, 20, icvDiag) + SETBITS(flags, 21, 24, dgDiag) + + record << flags; +} + void serialize_one(std::wostream & stream, const std::wstring & name, unsigned char type, unsigned char color, FullColorExt* colorExt) { CP_XML_WRITER(stream) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFBdr.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFBdr.h index e2e53d48c0..7cb2a3cca5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFBdr.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFBdr.h @@ -48,6 +48,7 @@ public: static const ElementType type = typeDXFBdr; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); int serialize(std::wostream & stream); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp index cca859c48c..202a8fa77b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.cpp @@ -43,6 +43,11 @@ BiffStructurePtr DXFFntD::clone() return BiffStructurePtr(new DXFFntD(*this)); } +DXFFntD::DXFFntD() +{ + stFontName = L""; +} + void DXFFntD::load(CFRecord& record) { global_info = record.getGlobalWorkbookInfo(); @@ -69,6 +74,21 @@ void DXFFntD::load(CFRecord& record) record >> ich >> cch >> iFnt; } +void DXFFntD::save(CFRecord& record) +{ + + unsigned char cchFont = stFontName.getSize(); + record << cchFont; + if(cchFont) + record << stFontName; + record.reserveNunBytes(63 - cchFont); + record << stxp << icvFore; + record.reserveNunBytes(4); // reserved + record << tsNinch << fSssNinch << fUlsNinch << fBlsNinch; + record.reserveNunBytes(4); // reserved + record << ich << cch << iFnt; +} + int DXFFntD::serialize(std::wostream & stream, bool extOnly) { std::map::iterator pFind; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h index 49e238b756..8ab877cf14 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFFntD.h @@ -48,15 +48,17 @@ class DXFFntD : public BiffStructure { BASE_STRUCTURE_DEFINE_CLASS_NAME(DXFFntD) public: + DXFFntD(); BiffStructurePtr clone(); static const ElementType type = typeDXFFntD; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); int serialize(std::wostream & stream, bool extOnly = false); - XLUnicodeStringNoCch stFontName; + XLUnicodeStringNoCch stFontName; Stxp stxp; _INT32 icvFore = 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp index 0c3bad5a25..807b9a37c0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.cpp @@ -116,6 +116,76 @@ void DXFN::load(CFRecord& record) } } +void DXFN::save(CFRecord& record) +{ + _UINT32 flags = 0; + SETBIT(flags, 0, alchNinch); + SETBIT(flags, 1, alcvNinch); + SETBIT(flags, 2, wrapNinch); + SETBIT(flags, 3, trotNinch); + SETBIT(flags, 4, kintoNinch); + SETBIT(flags, 5, cIndentNinch); + SETBIT(flags, 6, fShrinkNinch); + SETBIT(flags, 7, fMergeCellNinch); + + SETBIT(flags, 8, lockedNinch); + SETBIT(flags, 9, hiddenNinch); + + SETBIT(flags, 10, glLeftNinch); + SETBIT(flags, 11, glRightNinch); + SETBIT(flags, 12, glTopNinch); + SETBIT(flags, 13, glBottomNinch); + SETBIT(flags, 14, glDiagDownNinch); + SETBIT(flags, 15, glDiagUpNinch); + + SETBIT(flags, 16, flsNinch); + SETBIT(flags, 17, icvFNinch); + SETBIT(flags, 18, icvBNinch); + + SETBIT(flags, 19, ifmtNinch); + SETBIT(flags, 20, fIfntNinch); + + SETBIT(flags, 25, ibitAtrNum); + SETBIT(flags, 26, ibitAtrFnt); + SETBIT(flags, 27, ibitAtrAlc); + SETBIT(flags, 28, ibitAtrBdr); + SETBIT(flags, 29, ibitAtrPat); + SETBIT(flags, 30, ibitAtrProt); + + SETBIT(flags, 31, iReadingOrderNinch); + record << flags; + + unsigned short flags2 = 0; + + SETBIT(flags2, 0, fIfmtUser); + SETBIT(flags2, 2, fNewBorder); + SETBIT(flags2, 15, fZeroInited); + + record << flags2; + + if(ibitAtrNum) + { + dxfnum.parent = this; + record << dxfnum; + } + if(ibitAtrFnt) + { + record << dxffntd; + } + if(ibitAtrAlc) + { + record << dxfalc; + } + if(ibitAtrBdr) + { + record << dxfbdr; + } + if(ibitAtrProt) + { + record << dxfprot; + } +} + int DXFN::serialize(std::wostream & stream) { CP_XML_WRITER(stream) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.h index 9689ca0c2f..fc5091e1d4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN.h @@ -57,6 +57,7 @@ public: static const ElementType type = typeDXFN; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); int serialize(std::wostream & stream); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNum.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNum.cpp index 3f9c9bb8c6..1d6485ea2a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNum.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNum.cpp @@ -61,6 +61,17 @@ void DXFNum::load(CFRecord& record) fmt_id.ifmt = global_info->RegisterNumFormat(fmt_id.ifmt, user_defined.fmt.value()); // return update } +void DXFNum::save(CFRecord& record) +{ + if (parent->fIfmtUser) + { + record << user_defined; + } + else + { + record << fmt_id; + } +} int DXFNum::serialize(std::wostream & stream) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNum.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNum.h index d64b41f92c..7c4351f7f6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNum.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNum.h @@ -49,6 +49,7 @@ public: static const ElementType type = typeDXFNum; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); int serialize(std::wostream & stream); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.cpp index 10d688d034..ee17aab8ba 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.cpp @@ -55,6 +55,17 @@ void DXFNumUsr::load(CFRecord& record) record >> fmt; } +void DXFNumUsr::save(CFRecord& record) +{ + record.reserveNunBytes(2); + record << fmt; + cb = record.getRdPtr(); + record.resetPointerToBegin(); + record << cb; + record.skipNunBytes(cb - 2); + +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.h index 04f8d1458c..41fed9c000 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.h @@ -49,8 +49,9 @@ public: static const ElementType type = typeDXFNumUsr; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); - unsigned short cb; + unsigned short cb = 0; XLUnicodeString fmt; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFPat.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFPat.cpp index 96e46d1f85..8490931fb3 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFPat.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFPat.cpp @@ -52,6 +52,18 @@ void DXFPat::load(CFRecord& record) icvForeground = GETBITS(flags, 0, 6); icvBackground = GETBITS(flags, 7, 13); } + +void DXFPat::save(CFRecord& record) +{ + unsigned short flags = 0; + SETBITS(flags, 10, 15, fls); + record << flags; + flags = 0; + SETBITS(flags, 0, 6, icvForeground); + SETBITS(flags, 7, 13, icvBackground); + record << flags; +} + std::wstring GetPatternType(unsigned char fls) { std::wstring res; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFPat.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFPat.h index c70d49f230..6dd9dd3c7e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFPat.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFPat.h @@ -48,6 +48,7 @@ public: static const ElementType type = typeDXFPat; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); int serialize(std::wostream & stream); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFProt.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFProt.cpp index 25084ace45..a67d9fa722 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFProt.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFProt.cpp @@ -50,6 +50,14 @@ void DXFProt::load(CFRecord& record) fHidden = GETBIT(flags, 1); } +void DXFProt::save(CFRecord& record) +{ + unsigned short flags = 0; + SETBIT(flags, 0, fLocked) + SETBIT(flags, 1, fHidden) + record << flags; +} + int DXFProt::serialize(std::wostream & stream) { if (parent->lockedNinch && parent->hiddenNinch) return 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFProt.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFProt.h index 00bf745223..864b0f1060 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFProt.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFProt.h @@ -47,7 +47,7 @@ public: static const ElementType type = typeDXFProt; virtual void load(CFRecord& record); - + virtual void save(CFRecord& record); int serialize(std::wostream & stream); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.cpp index 5141227205..c658dd0171 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.cpp @@ -48,6 +48,11 @@ void Stxp::load(CFRecord& record) record.skipNunBytes(1); // unused } +void Stxp::save(CFRecord& record) +{ + record << twpHeight << ts << bls << sss << uls << bFamily << bCharSet; + record.reserveNunBytes(1); // unused +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h index 230b81b0b4..abbc3aea54 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Stxp.h @@ -48,6 +48,8 @@ public: static const ElementType type = typeStxp; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); + int twpHeight = 0; Ts ts; From 494b7b52cb77e0b48a9ff5de8667b2b4553c12c5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 2 Apr 2025 17:54:32 +0600 Subject: [PATCH 014/114] Add dxfn12 writing --- .../Format/Logic/Biff_structures/DXFN12.cpp | 19 +++++++++ .../Format/Logic/Biff_structures/DXFN12.h | 3 +- .../Logic/Biff_structures/DXFNumUsr.cpp | 6 +-- .../Format/Logic/Biff_structures/ExtProp.cpp | 40 +++++++++++++++++++ .../Format/Logic/Biff_structures/ExtProp.h | 3 +- .../Logic/Biff_structures/FullColorExt.cpp | 6 +++ .../Logic/Biff_structures/FullColorExt.h | 2 + .../Format/Logic/Biff_structures/GradStop.cpp | 6 +++ .../Format/Logic/Biff_structures/GradStop.h | 7 ++-- .../Logic/Biff_structures/XFExtGradient.cpp | 8 ++++ .../Logic/Biff_structures/XFExtGradient.h | 1 + .../Logic/Biff_structures/XFExtNoFRT.cpp | 12 ++++++ .../Format/Logic/Biff_structures/XFExtNoFRT.h | 1 + .../Logic/Biff_structures/XFPropGradient.h | 12 +++--- 14 files changed, 112 insertions(+), 14 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN12.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN12.cpp index 3f86ea9a06..4953a8e818 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN12.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN12.cpp @@ -67,6 +67,25 @@ void DXFN12::load(CFRecord& record) } } +void DXFN12::save(CFRecord& record) +{ + record.reserveNunBytes(4); + auto StartDataPose = record.getRdPtr(); + if(dxfn) + { + record >> *dxfn; + + if(dxfn->xfext != nullptr) + record << *dxfn->xfext; + cbDxf = record.getRdPtr() - StartDataPose; + record.RollRdPtrBack(cbDxf+4); + record << cbDxf; + record.skipNunBytes(cbDxf); + } + else + record.reserveNunBytes(2); +} + int DXFN12::serialize(std::wostream & stream) { if (!dxfn) return -1; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN12.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN12.h index e1f16f49e4..f779c65954 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN12.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFN12.h @@ -48,10 +48,11 @@ public: static const ElementType type = typeDXFN12; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); int serialize(std::wostream & stream); - _UINT32 cbDxf; + _UINT32 cbDxf = 0; DXFNPtr dxfn; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.cpp index ee17aab8ba..d2efaa15cb 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/DXFNumUsr.cpp @@ -57,13 +57,13 @@ void DXFNumUsr::load(CFRecord& record) void DXFNumUsr::save(CFRecord& record) { + auto cbPos = record.getRdPtr(); record.reserveNunBytes(2); record << fmt; - cb = record.getRdPtr(); - record.resetPointerToBegin(); + cb = record.getRdPtr() - cbPos; + record.RollRdPtrBack(cb); record << cb; record.skipNunBytes(cb - 2); - } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.cpp index 8a0805fe11..63b334a6de 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.cpp @@ -83,5 +83,45 @@ void ExtProp::load(CFRecord& record) } } +void ExtProp::save(CFRecord& record) +{ + unsigned short t = extType; + record << t << cb; + auto dataPos = record.getRdPtr(); + switch(extType) + { + case 0x0004: + case 0x0005: + case 0x0007: + case 0x0008: + case 0x0009: + case 0x000A: + case 0x000B: + case 0x000C: + case 0x000D: + { + record << extPropData.color; + }break; + case 0x0006: + { + record << extPropData.gradient_fill; + }break; + case 0x000E: + { + record << extPropData.font_scheme; + }break; + case 0x000F: + { + record << extPropData.indent_level; + }break; + default: + break; + } + cb = record.getRdPtr() - dataPos; + record.RollRdPtrBack(cb + 2); + cb += 4; + record << cb; + record.skipNunBytes(cb - 4); +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h index f601576bc3..7f10de7c8b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtProp.h @@ -47,10 +47,11 @@ public: BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); static const ElementType type = typeExtProp; - unsigned short cb; + unsigned short cb = 0; enum _type { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp index 1dc16fc177..e1751047c6 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.cpp @@ -49,6 +49,12 @@ void FullColorExt::load(CFRecord& record) record.skipNunBytes(8); //unused } +void FullColorExt::save(CFRecord& record) +{ + record << xclrType << nTintShade << xclrValue; + record.reserveNunBytes(8); //unused +} + int FullColorExt::serialize(std::wostream & stream, const std::wstring &node_name) { if (xclrType > 3) return 0;//not set diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h index d707b102fa..0bea974e66 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FullColorExt.h @@ -47,6 +47,8 @@ public: BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); + int serialize(std::wostream & stream, const std::wstring &sNode); static const ElementType type = typeFullColorExt; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/GradStop.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/GradStop.cpp index f96a541d7f..fdca00e4fc 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/GradStop.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/GradStop.cpp @@ -48,5 +48,11 @@ void GradStop::load(CFRecord& record) record >> numPosition >> numTint; } +void GradStop::save(CFRecord& record) +{ + record << xclrType << xclrValue; + + record << numPosition << numTint; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/GradStop.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/GradStop.h index 171da043a9..0c5f22509e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/GradStop.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/GradStop.h @@ -46,13 +46,14 @@ public: BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); static const ElementType type = typeGradStop; - _UINT16 xclrType; - _UINT32 xclrValue; + _UINT16 xclrType = 0; + _UINT32 xclrValue = 0; - Xnum numPosition; + Xnum numPosition; Xnum numTint; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.cpp index 2553e92342..66e19c4988 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.cpp @@ -55,6 +55,14 @@ void XFExtGradient::load(CFRecord& record) } } +void XFExtGradient::save(CFRecord& record) +{ + cGradStops = rgGradStops.size(); + record << gradient << cGradStops; + for(auto i : rgGradStops) + record << i; +} + int XFExtGradient::serialize(std::wostream & stream) { CP_XML_WRITER(stream) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h index 23482a781e..bde849f81a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtGradient.h @@ -47,6 +47,7 @@ public: BiffStructurePtr clone(); virtual void load(CFRecord& record); + virtual void save(CFRecord& record); int serialize(std::wostream & stream); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtNoFRT.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtNoFRT.cpp index 8368b2045a..63b2a28a2c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtNoFRT.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtNoFRT.cpp @@ -72,5 +72,17 @@ void XFExtNoFRT::load(CFRecord& record) } } +void XFExtNoFRT::save(CFRecord& record) +{ + record.reserveNunBytes(2); + unsigned short reserved2 = 0xFFFF; + record << reserved2; + record.reserveNunBytes(2); + unsigned short cexts = mapRgExt.size(); + record << cexts; + for(auto i:mapRgExt) + record << i.second; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtNoFRT.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtNoFRT.h index dd54ae1cde..375fa33d5a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtNoFRT.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFExtNoFRT.h @@ -50,6 +50,7 @@ public: static const ElementType type = typeXFExtNoFRT; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); std::map mapRgExt; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropGradient.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropGradient.h index 3602f29240..1fba52daa2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropGradient.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XFPropGradient.h @@ -60,13 +60,13 @@ public: void serialize_attr(CP_ATTR_NODE); int deserialize(XmlUtils::CXmlLiteReader& oReader); - bool type1; + bool type1 = 0; - double numDegree; - double numFillToLeft; - double numFillToRight; - double numFillToTop; - double numFillToBottom; + double numDegree = 0; + double numFillToLeft = 0; + double numFillToRight = 0; + double numFillToTop = 0; + double numFillToBottom = 0; }; } // namespace XLS From 8f14a0f30bff3859b7782b4c236b6ef3ddcb43e4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 2 Apr 2025 20:26:21 +0600 Subject: [PATCH 015/114] Fix cf writing --- MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.cpp index 3e16578c3c..3fdce0d056 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF.cpp @@ -84,18 +84,21 @@ void CF::writeFields(CFRecord& record) record << ct << cp; record.reserveNunBytes(4); auto ccePos = record.getRdPtr(); + record << rgbdxf; + auto rgce1pos = record.getRdPtr(); + auto dxfSize = rgce1pos - ccePos; rgce1.save(record); - unsigned short rgceSize = record.getRdPtr() - ccePos; - record.RollRdPtrBack(rgceSize + 4); + unsigned short rgceSize = record.getRdPtr() - rgce1pos; + record.RollRdPtrBack(rgceSize + dxfSize + 4); record << rgceSize; - record.skipNunBytes(rgceSize + 2); + record.skipNunBytes(2 + rgceSize + dxfSize); auto rgce2pos = record.getRdPtr(); rgce2.save(record); rgceSize = record.getRdPtr() - rgce2pos; record.RollRdPtrBack((record.getRdPtr() - ccePos) + 2); record << rgceSize; - record.skipNunBytes(rgce2pos+ rgceSize); + record.skipNunBytes((rgce2pos - ccePos) + rgceSize); } From bf89efd4715766c3b46a55bfddeca8a73f13e1a6 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 2 Apr 2025 22:00:58 +0600 Subject: [PATCH 016/114] Add cf12 writing --- .../Format/Logic/Biff_records/CF12.cpp | 38 ++++++++++++++++++- .../XlsFile/Format/Logic/Biff_records/CF12.h | 15 ++++---- .../Format/Logic/Biff_structures/CFColor.cpp | 23 +++++++++++ .../Format/Logic/Biff_structures/CFColor.h | 7 ++-- .../Logic/Biff_structures/CFDatabar.cpp | 13 +++++++ .../Format/Logic/Biff_structures/CFDatabar.h | 1 + .../Logic/Biff_structures/CFGradient.cpp | 33 ++++++++++++++++ .../Format/Logic/Biff_structures/CFGradient.h | 15 +++++--- .../Logic/Biff_structures/CFMStateItem.cpp | 6 +++ .../Logic/Biff_structures/CFMStateItem.h | 3 +- .../Logic/Biff_structures/CFMultistate.cpp | 15 ++++++++ .../Logic/Biff_structures/CFMultistate.h | 5 ++- .../Format/Logic/Biff_structures/CFVO.cpp | 13 +++++++ .../Format/Logic/Biff_structures/CFVO.h | 6 +-- .../Format/Logic/Biff_structures/LongRGB.h | 8 ++-- 15 files changed, 174 insertions(+), 27 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF12.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF12.cpp index aba57cf39a..5ed16aabb1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF12.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF12.cpp @@ -82,7 +82,7 @@ void CF12::readFields(CFRecord& record) record >> flags; fStopIfTrue = GETBIT(flags, 1); - record >> ipriority >> icfTemplate; + record >> ipriority >> icfTemplate; unsigned char cbTemplateParm; @@ -117,6 +117,42 @@ void CF12::readFields(CFRecord& record) dxfId_ = global_info->RegistrDxfn(strm.str()); } +void CF12::writeFields(CFRecord& record) +{ frtRefHeader.rt = 0x087A; + record << frtRefHeader; + record << ct << cp; + + record.reserveNunBytes(4); + auto ccePos = record.getRdPtr(); + record << dxf; + auto rgce1pos = record.getRdPtr(); + auto dxfSize = rgce1pos - ccePos; + rgce1.save(record); + unsigned short rgceSize = record.getRdPtr() - rgce1pos; + record.RollRdPtrBack(rgceSize + dxfSize + 4); + record << rgceSize; + record.skipNunBytes(2 + rgceSize + dxfSize); + + auto rgce2pos = record.getRdPtr(); + rgce2.save(record); + rgceSize = record.getRdPtr() - rgce2pos; + record.RollRdPtrBack((record.getRdPtr() - ccePos) + 2); + record << rgceSize; + record.skipNunBytes((rgce2pos - ccePos) + rgceSize); + + fmlaActive.save(record); + + unsigned char flags = 0; + + SETBIT(flags, 1, fStopIfTrue); + record << flags; + BYTE cbTemplateParm = 16; + record << ipriority << icfTemplate << cbTemplateParm; + record << rgbTemplateParms; + if(rgbCT != nullptr) + rgbCT->save(record); + +} int CF12::serialize(std::wostream & stream) { CFEx * cfEx = dynamic_cast(m_CFEx.get()); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF12.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF12.h index b6bd6250a9..83d9c1d378 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF12.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CF12.h @@ -54,6 +54,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCF12; @@ -61,8 +62,8 @@ public: FrtRefHeader frtRefHeader; - unsigned char ct; - unsigned char cp; + unsigned char ct = 0; + unsigned char cp = 0; DXFN12 dxf; @@ -70,16 +71,16 @@ public: CFParsedFormulaNoCCE rgce2; CFParsedFormula fmlaActive; - _UINT16 ipriority; - _UINT16 icfTemplate; + _UINT16 ipriority = 0; + _UINT16 icfTemplate = 0; CFExTemplateParams rgbTemplateParms; BiffStructurePtr rgbCT; //----------------------------- - bool fStopIfTrue; - int ipriority_; - int dxfId_; + bool fStopIfTrue = 0; + int ipriority_ = 0; + int dxfId_ = 0; BaseObjectPtr m_CFEx; BaseObjectPtr m_CF12_2; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFColor.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFColor.cpp index 25729fb708..f94bdfdc7e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFColor.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFColor.cpp @@ -76,6 +76,29 @@ void CFColor::load(CFRecord& record) record >> numTint; } +void CFColor::save(CFRecord& record) +{ + record << xclrType; + switch(xclrType.type) + { + case XColorType::XCLRINDEXED: + record << icv; + break; + case XColorType::XCLRRGB: + record << rgb; + break; + case XColorType::XCLRTHEMED: + record << theme; + break; + case XColorType::XCLRNINCHED: + case XColorType::XCLRAUTO: + record.reserveNunBytes(4); // ignored + break; + default: + break; + } + record << numTint; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFColor.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFColor.h index 7baa402f31..692aa1ff93 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFColor.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFColor.h @@ -51,12 +51,13 @@ public: static const ElementType type = typeCFColor; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); XColorType xclrType; - ColorICV icv; + ColorICV icv = 0; LongRGBA rgb; - ColorTheme theme; - double numTint; + ColorTheme theme = 0; + double numTint = 0; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFDatabar.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFDatabar.cpp index 1fff785131..f5cf085c23 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFDatabar.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFDatabar.cpp @@ -60,6 +60,19 @@ void CFDatabar::load(CFRecord& record) cfvoDB2.load(record); } +void CFDatabar::save(CFRecord& record) +{ + record.reserveNunBytes(3); // unused + + unsigned char flags = 0; + SETBIT(flags, 0, fRightToLeft); + SETBIT(flags, 1, fShowValue); + record << flags; + record << iPercentMin << iPercentMax << color; + cfvoDB1.save(record); + cfvoDB2.save(record); +} + int CFDatabar::serialize(std::wostream & stream) { CP_XML_WRITER(stream) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFDatabar.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFDatabar.h index d54f6b48ac..85db68ea97 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFDatabar.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFDatabar.h @@ -47,6 +47,7 @@ public: static const ElementType type = typeCFDatabar; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual int serialize(std::wostream & _stream); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFGradient.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFGradient.cpp index 297b810f06..7ddadc3bcb 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFGradient.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFGradient.cpp @@ -49,6 +49,15 @@ void CFGradientInterpItem::load(CFRecord& record) //record >> val; numDomain = val << 32; //record >> val; numDomain = val; } +void CFGradientInterpItem::save(CFRecord& record) +{ + cfvo.save(record); + record << numDomain; + //record.skipNunBytes(8); + //int val; + //record >> val; numDomain = val << 32; + //record >> val; numDomain = val; +} //--------------------------------------------------------------------------------------------- BiffStructurePtr CFGradientItem::clone() { @@ -66,6 +75,13 @@ void CFGradientItem::load(CFRecord& record) color.load(record); } +void CFGradientItem::save(CFRecord& record) +{ + record << numGrange; + + color.save(record); +} + //-------------------------------------------------------------------------------------------- BiffStructurePtr CFGradient::clone() @@ -113,6 +129,23 @@ void CFGradient::load(CFRecord& record) rgCurve.push_back(item); } } +void CFGradient::save(CFRecord& record) +{ + record.reserveNunBytes(3); + cInterpCurve = rgInterp.size(); + cGradientCurve = cInterpCurve; + record << cInterpCurve << cGradientCurve; + unsigned char flags = 0; + SETBIT(flags, 0, fClamp); + SETBIT(flags, 1, fBackground); + record << flags; + for(auto i : rgInterp) + if(i!= nullptr) + record << i; + for(auto i : rgCurve) + if(i!= nullptr) + record << i; +} int CFGradient::serialize(std::wostream & stream) { CP_XML_WRITER(stream) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFGradient.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFGradient.h index 99cad2db6b..919abfd3df 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFGradient.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFGradient.h @@ -47,10 +47,11 @@ public: static const ElementType type = typeAnyObject; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); - CFVO cfvo; - double numDomain; + CFVO cfvo; + double numDomain = 0; }; typedef boost::shared_ptr CFGradientInterpItemPtr; @@ -64,6 +65,7 @@ public: static const ElementType type = typeAnyObject; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); Xnum numGrange; CFColor color; @@ -79,14 +81,15 @@ public: static const ElementType type = typeCFGradient; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual int serialize(std::wostream & stream); - unsigned char cInterpCurve; //MUST be 0x2 or 0x3. - unsigned char cGradientCurve; // == cInterpCurve + unsigned char cInterpCurve = 0x2; //MUST be 0x2 or 0x3. + unsigned char cGradientCurve = 0x2; // == cInterpCurve - bool fClamp; - bool fBackground; + bool fClamp = 0; + bool fBackground = 0; std::vectorrgInterp; std::vector rgCurve; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMStateItem.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMStateItem.cpp index a889da4f90..9ddbeaf5e5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMStateItem.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMStateItem.cpp @@ -48,6 +48,12 @@ void CFMStateItem::load(CFRecord& record) record.skipNunBytes(4); // unused } +void CFMStateItem::save(CFRecord& record) +{ + cfvo.save(record); + record << fEqual; + record.reserveNunBytes(4); +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMStateItem.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMStateItem.h index 332f8502de..29fe2e5a4f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMStateItem.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMStateItem.h @@ -49,9 +49,10 @@ public: static const ElementType type = typeCFMStateItem; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); CFVO cfvo; - Boolean fEqual; + Boolean fEqual = 0; }; typedef boost::shared_ptr CFMStateItemPtr; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMultistate.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMultistate.cpp index f0ffb343b5..71a9b75d43 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMultistate.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMultistate.cpp @@ -59,6 +59,21 @@ void CFMultistate::load(CFRecord& record) rgStates.push_back(item); } } + +void CFMultistate::save(CFRecord& record) +{ + record.reserveNunBytes(3); + cStates = rgStates.size(); + record << cStates << iIconSet; + unsigned char flags = 0; + SETBIT(flags, 0, fIconOnly); + SETBIT(flags, 2, fReverse); + record << flags; + for (auto i : rgStates) + if(i != nullptr) + i->save(record); +} + int CFMultistate::serialize(std::wostream & stream) { CP_XML_WRITER(stream) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMultistate.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMultistate.h index 20faba3aa4..cfdfc3bb76 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMultistate.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFMultistate.h @@ -46,11 +46,12 @@ public: static const ElementType type = typeCFMultistate; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); virtual int serialize(std::wostream & _stream); - unsigned char cStates; - unsigned char iIconSet; + unsigned char cStates = 0; + unsigned char iIconSet = 0; bool fIconOnly; bool fReverse; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVO.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVO.cpp index 60e380f598..6ce51af4f5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVO.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVO.cpp @@ -52,6 +52,19 @@ void CFVO::load(CFRecord& record) } } +void CFVO::save(CFRecord& record) +{ + record << cfvoType; + if(!fmla.rgce.sequence.empty()) + { + fmla.save(record); + } + else if(cfvoType != 2 && cfvoType != 3) + { + record << numValue; + } +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVO.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVO.h index 0781098757..4e27901145 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVO.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CFVO.h @@ -46,11 +46,11 @@ public: static const ElementType type = typeCFVO; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); - - unsigned char cfvoType; + unsigned char cfvoType = 0; CFVOParsedFormula fmla; - double numValue; + double numValue = 0; }; typedef boost::shared_ptr CFVOPtr; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/LongRGB.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/LongRGB.h index 88328957e0..8740b05624 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/LongRGB.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/LongRGB.h @@ -51,10 +51,10 @@ public: void load(CFRecord& record) override; void save(CFRecord& record) override; - unsigned char red; - unsigned char green; - unsigned char blue; - unsigned char alpha; + unsigned char red = 0; + unsigned char green = 0; + unsigned char blue = 0; + unsigned char alpha = 0; std::wstring strARGB; std::wstring strRGB; From 6f66b0c5338eef17dce4452d507a9655f89a5920 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 3 Apr 2025 19:59:03 +0600 Subject: [PATCH 017/114] Add condfmt12 writing --- .../Format/Logic/Biff_records/CondFmt12.cpp | 7 +++++++ .../Format/Logic/Biff_records/CondFmt12.h | 1 + .../Logic/Biff_structures/CondFmtStructure.h | 6 +++--- .../Format/Logic/Biff_structures/SqRefU.cpp | 17 +++++++++++++++++ .../Format/Logic/Biff_structures/SqRefU.h | 1 + .../Format/Logic/Biff_unions/CONDFMT12.h | 1 + .../Format/Logic/Biff_unions/CONDFMT12_bu.cpp | 11 +++++++++++ 7 files changed, 41 insertions(+), 3 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt12.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt12.cpp index 5776d34702..52c12813f0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt12.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt12.cpp @@ -57,6 +57,13 @@ void CondFmt12::readFields(CFRecord& record) record >> mainCF; } +void CondFmt12::writeFields(CFRecord& record) +{ + frtRefHeaderU.rt = 0x0879; + frtRefHeaderU.grbitFrt.fFrtRef = 1; + record << frtRefHeaderU; + record << mainCF; +} const CellRef CondFmt12::getLocation() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt12.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt12.h index c0e67b9cf2..bb259c6da5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt12.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt12.h @@ -52,6 +52,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCondFmt12; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.h index 01d2f9c5c2..afa2bc34f8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CondFmtStructure.h @@ -51,9 +51,9 @@ public: const CellRef getLocation() const; - unsigned short ccf; - bool fToughRecalc; - unsigned short nID; + unsigned short ccf = 0; + bool fToughRecalc = 0; + unsigned short nID = 0; Ref8U refBound; SqRefU sqref; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SqRefU.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SqRefU.cpp index 98720c804e..c5c9d61a9d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SqRefU.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SqRefU.cpp @@ -32,6 +32,7 @@ #include "SqRefU.h" #include "CellRangeRef.h" +#include namespace XLS { @@ -55,6 +56,22 @@ void SqRefU::load(CFRecord& record) strValue += std::wstring (ref8.toString(false).c_str()) + ((i == cref - 1) ? L"" : L" "); } } +void SqRefU::save(CFRecord& record) +{ + std::vector results; + + boost::algorithm::split(results, strValue, boost::is_any_of(L" ")); + unsigned short crfx = results.size(); + + record << crfx; + + for (auto& item : results) + { + Ref8U rfx(item); + record << rfx; + } +} + struct refs_sort { inline bool operator() (const CellRangeRef& ref1, const CellRangeRef& ref2) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SqRefU.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SqRefU.h index dc7bd005af..793a988a62 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SqRefU.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SqRefU.h @@ -48,6 +48,7 @@ public: static const ElementType type = typeSqRefU; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); const CellRef getLocationFirstCell() const; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT12.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT12.h index 821095bdbb..e43095177a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT12.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT12.h @@ -48,6 +48,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); static const ElementType type = typeCONDFMT12; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT12_bu.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT12_bu.cpp index e6ee435357..50e83e9b5e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT12_bu.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT12_bu.cpp @@ -96,6 +96,17 @@ const bool CONDFMT12::loadContent(BinProcessor& proc) return true; } + +const bool CONDFMT12::saveContent(BinProcessor& proc) +{ + if(m_CondFmt12 != nullptr) + proc.mandatory(*m_CondFmt12); + for(auto i : m_arCF12) + if(i != nullptr) + proc.mandatory(*i); + return true; +} + int CONDFMT12::serialize(std::wostream & stream) { if (!m_CondFmt12) return 0; From 25fa05b70183479759494466a87196e66918da4a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 3 Apr 2025 20:17:58 +0600 Subject: [PATCH 018/114] add condfmts union writing --- .../XlsFile/Format/Logic/Biff_unions/CONDFMTS.cpp | 15 +++++++++++++++ .../XlsFile/Format/Logic/Biff_unions/CONDFMTS.h | 1 + 2 files changed, 16 insertions(+) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMTS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMTS.cpp index d2c56ae512..339ab5026c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMTS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMTS.cpp @@ -199,6 +199,21 @@ const bool CONDFMTS::loadContent(BinProcessor& proc) return res; } +const bool CONDFMTS::saveContent(BinProcessor& proc) +{ + for(auto i : m_arCONDFMT) + if(i != nullptr) + proc.mandatory(*i); + for(auto i : m_arCFEx) + { + if(i.ex != nullptr) + proc.mandatory(*i.ex); + if(i.cf12 != nullptr) + proc.mandatory(*i.cf12); + } + return true; +} + int CONDFMTS::serialize(std::wostream & stream) { if (m_arCONDFMT.empty()) return 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMTS.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMTS.h index 649503e374..8da261b2a2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMTS.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMTS.h @@ -46,6 +46,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); static const ElementType type = typeCONDFMTS; From c8ca725523949442ed9ca1be1582dadde520c7d8 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 4 Apr 2025 17:53:24 +0600 Subject: [PATCH 019/114] Add hlink writing --- .../Format/Logic/Biff_records/HLink.cpp | 8 +++ .../XlsFile/Format/Logic/Biff_records/HLink.h | 1 + .../Logic/Biff_records/HLinkTooltip.cpp | 11 ++++ .../Format/Logic/Biff_records/HLinkTooltip.h | 1 + .../Logic/Biff_structures/AntiMoniker.cpp | 4 ++ .../Logic/Biff_structures/AntiMoniker.h | 3 +- .../Biff_structures/CompositeMoniker.cpp | 8 +++ .../Logic/Biff_structures/CompositeMoniker.h | 1 + .../Logic/Biff_structures/FileMoniker.cpp | 20 +++++++ .../Logic/Biff_structures/FileMoniker.h | 15 ++--- .../Biff_structures/FrtRefHeaderNoGrbit.cpp | 5 ++ .../Biff_structures/FrtRefHeaderNoGrbit.h | 1 + .../Biff_structures/HyperlinkMoniker.cpp | 10 ++++ .../Logic/Biff_structures/HyperlinkMoniker.h | 1 + .../Logic/Biff_structures/HyperlinkObject.cpp | 60 ++++++++++++++++++- .../Logic/Biff_structures/HyperlinkObject.h | 24 ++++---- .../Logic/Biff_structures/ItemMoniker.cpp | 24 ++++++++ .../Logic/Biff_structures/ItemMoniker.h | 1 + .../Logic/Biff_structures/URLMoniker.cpp | 13 ++++ .../Format/Logic/Biff_structures/URLMoniker.h | 1 + .../XlsFile/Format/Logic/Biff_unions/HLINK.h | 1 + .../Format/Logic/Biff_unions/HLINK_bu.cpp | 9 +++ 22 files changed, 202 insertions(+), 20 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp index 44a3957f24..4670d2ad29 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp @@ -58,5 +58,13 @@ void HLink::readFields(CFRecord& record) hlinkClsid = STR::guid2bstr(clsid); } +void HLink::writeFields(CFRecord& record) +{ + record << ref8; + _GUID_ guid_num(0, 0, 0, 0); + STR::bstr2guid(hlinkClsid, guid_num); + record << guid_num << hyperlink; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.h index 21740e3e9a..d79b2e0bca 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.h @@ -52,6 +52,7 @@ public: void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeHLink; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLinkTooltip.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLinkTooltip.cpp index 8e51391797..a2c8ed11a8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLinkTooltip.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLinkTooltip.cpp @@ -65,5 +65,16 @@ void HLinkTooltip::readFields(CFRecord& record) wzTooltip = std::wstring (wzTooltip_prep.c_str()); } +void HLinkTooltip::writeFields(CFRecord& record) +{ + FrtRefHeaderNoGrbit frtRefHeaderNoGrbit(rt_HLinkTooltip); + frtRefHeaderNoGrbit.ref8 = ref_; + record << frtRefHeaderNoGrbit; + if(wzTooltip.empty() || wzTooltip.at(wzTooltip.size() -1) != L'\0') + wzTooltip += L'\0'; + for(auto i : wzTooltip) + record << i; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLinkTooltip.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLinkTooltip.h index 214a180dbe..562f278a7b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLinkTooltip.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLinkTooltip.h @@ -47,6 +47,7 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeHLinkTooltip; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/AntiMoniker.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/AntiMoniker.cpp index 6c44311662..a66c27c904 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/AntiMoniker.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/AntiMoniker.cpp @@ -46,6 +46,10 @@ void AntiMoniker::load(XLS::CFRecord& record) record >> count; } +void AntiMoniker::save(XLS::CFRecord& record) +{ + record << count; +} } // namespace OSHARED diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/AntiMoniker.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/AntiMoniker.h index a638d1e2cf..e7b20a8fb4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/AntiMoniker.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/AntiMoniker.h @@ -47,9 +47,10 @@ public: static const XLS::ElementType type = XLS::typeAntiMoniker; virtual void load(XLS::CFRecord& record); + virtual void save(XLS::CFRecord& record); - _UINT32 count; + _UINT32 count = 0; }; } // namespace OSHARED diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CompositeMoniker.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CompositeMoniker.cpp index 0ad0520b2d..6a1951014f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CompositeMoniker.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CompositeMoniker.cpp @@ -65,6 +65,14 @@ void CompositeMoniker::load(XLS::CFRecord& record) } } +void CompositeMoniker::save(XLS::CFRecord& record) +{ + unsigned int cMonikers = monikerArray.size(); + record << cMonikers; + for(auto i : monikerArray) + record << i; +} + } // namespace OSHARED diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CompositeMoniker.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CompositeMoniker.h index f888e650f0..de5287fc24 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CompositeMoniker.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CompositeMoniker.h @@ -48,6 +48,7 @@ public: static const XLS::ElementType type = XLS::typeCompositeMoniker; virtual void load(XLS::CFRecord& record); + virtual void save(XLS::CFRecord& record); std::vector monikerArray; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileMoniker.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileMoniker.cpp index 2a1a656833..ea598e212b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileMoniker.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileMoniker.cpp @@ -73,6 +73,26 @@ void FileMoniker::load(XLS::CFRecord& record) } } +void FileMoniker::save(XLS::CFRecord& record) +{ + _UINT32 ansiLength = ansiPath.size(); + record << cAnti << ansiLength << ansiPath << endServer << versionNumber; + record.reserveNunBytes(20); + if(!unicodePath.empty()) + { + cbUnicodePathSize = (unicodePath.size() * 2) + 6; + _UINT32 cbUnicodePathBytes = (unicodePath.size() * 2); + record << cbUnicodePathSize << cbUnicodePathBytes << usKeyValue; + for(auto i : unicodePath) + record << i; + + } + else + record.reserveNunBytes(4); + + + +} } // namespace OSHARED diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileMoniker.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileMoniker.h index c0809ce826..2f4731b671 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileMoniker.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileMoniker.h @@ -49,15 +49,16 @@ public: static const XLS::ElementType type = XLS::typeFileMoniker; virtual void load(XLS::CFRecord& record); + virtual void save(XLS::CFRecord& record); - _UINT16 cAnti; - std::string ansiPath; - _UINT16 endServer; - _UINT16 versionNumber; - _UINT32 cbUnicodePathSize; - _UINT16 usKeyValue; - std::wstring unicodePath; + _UINT16 cAnti = 0; + std::string ansiPath = ""; + _UINT16 endServer = 0; + _UINT16 versionNumber = 0; + _UINT32 cbUnicodePathSize = 0; + _UINT16 usKeyValue = 3; + std::wstring unicodePath = L""; }; } // namespace OSHARED diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeaderNoGrbit.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeaderNoGrbit.cpp index 5d0179b99b..1fad5f6d63 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeaderNoGrbit.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeaderNoGrbit.cpp @@ -61,6 +61,11 @@ void FrtRefHeaderNoGrbit::load(CFRecord& record) record >> ref8; } +void FrtRefHeaderNoGrbit::save(CFRecord& record) +{ + record << rt; + record << ref8; +} } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeaderNoGrbit.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeaderNoGrbit.h index c4b76f9f3b..298472e379 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeaderNoGrbit.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FrtRefHeaderNoGrbit.h @@ -52,6 +52,7 @@ public: static const ElementType type = typeFrtRefHeaderNoGrbit; virtual void load(CFRecord& record); + virtual void save(CFRecord& record); CFRecordType::TypeId rt; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkMoniker.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkMoniker.cpp index b79bd5e5f0..c9ffe63555 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkMoniker.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkMoniker.cpp @@ -131,6 +131,16 @@ void HyperlinkMoniker::load(XLS::CFRecord& record) } } +void HyperlinkMoniker::save(XLS::CFRecord& record) +{ + _GUID_ clsid(0, 0, 0, 0); + STR::bstr2guid(monikerClsid, clsid); + record << clsid; + if (data) + { + data->save(record); + } +} } // namespace OSHARED diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkMoniker.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkMoniker.h index cb57671f9f..08b16c420d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkMoniker.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkMoniker.h @@ -45,6 +45,7 @@ public: XLS::BiffStructurePtr clone(); virtual void load(XLS::CFRecord& record); + virtual void save(XLS::CFRecord& record); virtual void load(IBinaryReader* reader); static const XLS::ElementType type = XLS::typeHyperlinkMoniker; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.cpp index 4c9312f715..9fed5ce6af 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.cpp @@ -89,6 +89,55 @@ void HyperlinkObject::load(XLS::CFRecord& record) } } +void HyperlinkObject::save(XLS::CFRecord& record) +{ + record << streamVersion; + { + _UINT32 flags = 0; + SETBIT(flags, 0, hlstmfHasMoniker); + SETBIT(flags, 1, hlstmfIsAbsolute); + SETBIT(flags, 2, hlstmfIsAbsolute); + SETBIT(flags, 3, hlstmfHasLocationStr); + SETBIT(flags, 4, hlstmfHasDisplayName); + SETBIT(flags, 5, hlstmfHasGUID); + SETBIT(flags, 6, hlstmfHasCreationTime); + SETBIT(flags, 7, hlstmfHasFrameName); + SETBIT(flags, 8, hlstmfMonikerSavedAsStr); + SETBIT(flags, 9, hlstmfAbsFromGetdataRel); + record << flags; + } + if(hlstmfHasDisplayName) + { + saveHyperlinkString(record, displayName); + } + if(hlstmfHasFrameName) + { + saveHyperlinkString(record, targetFrameName); + } + if(hlstmfHasMoniker && hlstmfMonikerSavedAsStr) + { + saveHyperlinkString(record, moniker); + } + if(hlstmfHasMoniker && !hlstmfMonikerSavedAsStr) + { + record << oleMoniker; + } + if(hlstmfHasLocationStr) + { + saveHyperlinkString(record, location); + } + if(hlstmfHasGUID) + { + _GUID_ guid_num; + STR::bstr2guid(guid, guid_num); + record << guid_num; + } + if(hlstmfHasCreationTime) + { + record.storeAnyData(fileTime); + } +} + std::wstring HyperlinkObject::loadHyperlinkString(XLS::CFRecord& record) { std::wstring result; @@ -111,6 +160,16 @@ std::wstring HyperlinkObject::loadHyperlinkString(XLS::CFRecord& record) return result; } +void HyperlinkObject::saveHyperlinkString(XLS::CFRecord& record, std::wstring hlinkString) +{ + _INT32 size = hlinkString.size(); + record << size; + for(auto i : hlinkString) + { + record << i; + } +} + std::wstring HyperlinkObject::loadHyperlinkString(IBinaryReader* reader) { std::wstring result; @@ -188,6 +247,5 @@ void HyperlinkObject::load(IBinaryReader* reader) } } - } // namespace OSHARED diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.h index 53a1a81ea3..c380e23a51 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.h @@ -55,25 +55,27 @@ public: XLS::BiffStructurePtr clone(); virtual void load(XLS::CFRecord& record); + virtual void save(XLS::CFRecord& record); void load(IBinaryReader* reader); std::wstring loadHyperlinkString(XLS::CFRecord& record); + void saveHyperlinkString(XLS::CFRecord& record, std::wstring hlinkString); std::wstring loadHyperlinkString(IBinaryReader* reader); - _UINT32 streamVersion; + _UINT32 streamVersion = 2; static const XLS::ElementType type = XLS::typeHyperlinkObject; - bool hlstmfHasMoniker; - bool hlstmfIsAbsolute; - bool hlstmfSiteGaveDisplayName; - bool hlstmfHasLocationStr; - bool hlstmfHasDisplayName; - bool hlstmfHasGUID; - bool hlstmfHasCreationTime; - bool hlstmfHasFrameName; - bool hlstmfMonikerSavedAsStr; - bool hlstmfAbsFromGetdataRel; + bool hlstmfHasMoniker = 0; + bool hlstmfIsAbsolute = 0; + bool hlstmfSiteGaveDisplayName = 0; + bool hlstmfHasLocationStr = 0; + bool hlstmfHasDisplayName = 0; + bool hlstmfHasGUID = 0; + bool hlstmfHasCreationTime = 0; + bool hlstmfHasFrameName = 0; + bool hlstmfMonikerSavedAsStr = 0; + bool hlstmfAbsFromGetdataRel = 0; std::wstring displayName; std::wstring targetFrameName; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ItemMoniker.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ItemMoniker.cpp index 36cdf7c3c0..4250a28b28 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ItemMoniker.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ItemMoniker.cpp @@ -86,6 +86,30 @@ void ItemMoniker::load(XLS::CFRecord& record) } +void ItemMoniker::save(XLS::CFRecord& record) +{ + if(delimiterAnsi.empty() || delimiterAnsi.at(delimiterAnsi.size()-1) != '\0') + { + delimiterAnsi += '\0'; + } + _UINT32 length = delimiterAnsi.size() + (delimiterUnicode.size() * 2); + record << length; + for(auto i : delimiterAnsi) + record << i; + for(auto i : delimiterUnicode) + record << i; + + if(itemAnsi.empty() || itemAnsi.at(itemAnsi.size()-1) != '\0') + { + itemAnsi += '\0'; + } + length = itemAnsi.size() + (itemUnicode.size() * 2); + record << length; + for(auto i : itemAnsi) + record << i; + for(auto i : itemUnicode) + record << i; +} } // namespace OSHARED diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ItemMoniker.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ItemMoniker.h index 7779da432f..89d3ccdfa4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ItemMoniker.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ItemMoniker.h @@ -49,6 +49,7 @@ public: static const XLS::ElementType type = XLS::typeItemMoniker; virtual void load(XLS::CFRecord& record); + virtual void save(XLS::CFRecord& record); std::string delimiterAnsi; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/URLMoniker.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/URLMoniker.cpp index edf93b94fd..7e2d4dcaf7 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/URLMoniker.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/URLMoniker.cpp @@ -74,6 +74,19 @@ void URLMoniker::load(XLS::CFRecord& record) } } +void URLMoniker::save(XLS::CFRecord& record) +{ + if(!url.empty() && url.at(url.size()-1) != L'\0') + { + url+= L'\0'; + } + _UINT32 length = url.size() * 2; + record << length; + for(auto i : url) + { + record << i; + } +} } // namespace OSHARED diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/URLMoniker.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/URLMoniker.h index 26808c088a..480b252600 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/URLMoniker.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/URLMoniker.h @@ -48,6 +48,7 @@ public: XLS::BiffStructurePtr clone(); virtual void load(XLS::CFRecord& record); + virtual void save(XLS::CFRecord& record); static const XLS::ElementType type = XLS::typeURLMoniker; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/HLINK.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/HLINK.h index cca6088625..d2c4147654 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/HLINK.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/HLINK.h @@ -48,6 +48,7 @@ public: BaseObjectPtr clone(); virtual const bool loadContent(BinProcessor& proc); + virtual const bool saveContent(BinProcessor& proc); static const ElementType type = typeHLINK; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/HLINK_bu.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/HLINK_bu.cpp index 870b8fbf4d..02047d7cd2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/HLINK_bu.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/HLINK_bu.cpp @@ -73,5 +73,14 @@ const bool HLINK::loadContent(BinProcessor& proc) return true; } +const bool HLINK::saveContent(BinProcessor& proc) +{ + if(m_HLink != nullptr) + proc.mandatory(*m_HLink); + if(m_HLinkTooltip != nullptr) + proc.mandatory(*m_HLinkTooltip); + return true; +} + } // namespace XLS From 3d9a783d461869c9f808feae38982e45e0ece006 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 7 Apr 2025 18:31:40 +0600 Subject: [PATCH 020/114] fix globals writing --- .../XlsFile/Format/Logic/Biff_records/BOF.h | 24 +++++++++---------- .../Format/Logic/Biff_records/CalcMode.cpp | 5 ++++ .../Format/Logic/Biff_records/CalcMode.h | 3 ++- .../Format/Logic/Biff_records/CalcRefMode.cpp | 5 ++++ .../Format/Logic/Biff_records/CalcRefMode.h | 3 ++- .../Logic/Biff_records/CalcSaveRecalc.h | 2 +- .../Format/Logic/Biff_records/DBCell.h | 2 +- .../Logic/Biff_records/DefaultRowHeight.cpp | 5 ++-- .../Format/Logic/Biff_structures/FileOffset.h | 2 +- .../Format/Logic/Biff_unions/CELLTABLE.cpp | 19 +++++++++++---- .../Format/Logic/Biff_unions/CELLTABLE.h | 2 +- .../Format/Logic/Biff_unions/GLOBALS.cpp | 18 ++++++++++++-- 12 files changed, 64 insertions(+), 26 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.h index a3c9a54057..0a164675c4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.h @@ -72,21 +72,21 @@ public: //----------------------------- - _UINT16 vers = 0; + _UINT16 vers = 0x0600; _UINT16 dt = 0; _UINT16 rupBuild = 0; - _UINT16 rupYear = 0; + _UINT16 rupYear = 0x07CC; - bool fWin; - bool fRisc; - bool fBeta; - bool fWinAny; - bool fMacAny; - bool fBetaAny; - bool fRiscAny; - bool fOOM; - bool fGlJmp; - bool fFontLimit; + bool fWin = 1; + bool fRisc = 0; + bool fBeta = 0; + bool fWinAny = 1; + bool fMacAny = 0; + bool fBetaAny = 0; + bool fRiscAny = 0; + bool fOOM = 0; + bool fGlJmp = 0; + bool fFontLimit = 0; _UINT16 verXLHigh = 0; unsigned char verLowestBiff = 0; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcMode.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcMode.cpp index 1d19d925ba..1c2bde7fa2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcMode.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcMode.cpp @@ -55,5 +55,10 @@ void CalcMode::readFields(CFRecord& record) record >> nAutoRecalc; } +void CalcMode::writeFields(CFRecord& record) +{ + record << nAutoRecalc; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcMode.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcMode.h index 52b3f07599..f1cd76af2b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcMode.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcMode.h @@ -46,10 +46,11 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCalcMode; - unsigned short nAutoRecalc; + unsigned short nAutoRecalc = 1; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcRefMode.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcRefMode.cpp index b81ca78bc1..64d6f34f25 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcRefMode.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcRefMode.cpp @@ -55,5 +55,10 @@ void CalcRefMode::readFields(CFRecord& record) record >> fRef; } +void CalcRefMode::writeFields(CFRecord& record) +{ + record << fRef; +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcRefMode.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcRefMode.h index 8a2d8fd988..dfda1c175f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcRefMode.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcRefMode.h @@ -47,11 +47,12 @@ public: BaseObjectPtr clone(); void readFields(CFRecord& record); + void writeFields(CFRecord& record); static const ElementType type = typeCalcRefMode; //----------------------------- - Boolean fRef; + Boolean fRef = 1; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.h index b4a8cfcafc..ad0afa7dc9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/CalcSaveRecalc.h @@ -51,7 +51,7 @@ public: static const ElementType type = typeCalcSaveRecalc; //----------------------------- - Boolean fSaveRecalc = false; + Boolean fSaveRecalc = true; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.h index 5d33b4e8ab..c3fa5cc947 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DBCell.h @@ -54,7 +54,7 @@ public: static const ElementType type = typeDBCell; //----------------------------- - _UINT32 dbRtrw; + _UINT32 dbRtrw = 0; BiffStructurePtrVector rgdb; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.cpp index b77db5ad46..b877a2b946 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefaultRowHeight.cpp @@ -81,8 +81,9 @@ namespace XLS void DefaultRowHeight::writeFields(CFRecord& record) { - unsigned short flags; - record >> flags; + if(miyRw == -1) + miyRw = 290; + unsigned short flags = 0; SETBIT(flags, 0, fUnsynced); SETBIT(flags, 1, fDyZero); diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.h index 7cf73c47d7..62b749d210 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/FileOffset.h @@ -50,7 +50,7 @@ public: virtual void save(CFRecord& record); - unsigned short offset; + unsigned short offset = 0; }; typedef boost::shared_ptr FileOffsetPtr; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp index 4cf54485f0..d7a0df070d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.cpp @@ -147,14 +147,25 @@ const bool CELL_GROUP::loadContent(BinProcessor& proc) } const bool CELL_GROUP::saveContent(BinProcessor& proc) { - if(m_row != nullptr) - proc.mandatory(*m_row); + for(auto i: m_arRows) + if(i != nullptr) + proc.mandatory(*i); for(auto i : m_arCells) if(i != nullptr) proc.mandatory(*i); - for(auto i : m_DBCells) + { + DBCell dbcell; + for(auto i: m_arRows) + { + FileOffsetPtr element(new FileOffset); + dbcell.rgdb.push_back(element); + } + proc.mandatory(dbcell); + + } + /*for(auto i : m_DBCells) if(i != nullptr) - proc.mandatory(*i); + proc.mandatory(*i);*/ return true; } //----------------------------------------------------------------------------------------------------------------- diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h index 1c1a386c1a..42fe591dfd 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h @@ -86,7 +86,7 @@ public: static const ElementType type = typeCELL_GROUP; //--------------------------------------------------------------------------- - BaseObjectPtr m_row;//for xls writing + std::vector m_arRows;//for xls writing std::vector m_arCells; std::list m_DBCells; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.cpp index db68b33891..4f4ceeb8cf 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/GLOBALS.cpp @@ -160,12 +160,16 @@ const bool GLOBALS::saveContent(BinProcessor& proc) { if(m_CalcMode != nullptr) proc.mandatory(*m_CalcMode); - if(m_CalcMode != nullptr) - proc.mandatory(*m_CalcMode); + else + proc.mandatory(); + proc.optional(); if(m_CalcRefMode != nullptr) proc.mandatory(*m_CalcRefMode); + else + proc.mandatory(); + proc.optional(); proc.optional(); proc.optional(); @@ -175,12 +179,22 @@ const bool GLOBALS::saveContent(BinProcessor& proc) if(m_Guts != nullptr) proc.mandatory(*m_Guts); + else + proc.mandatory(); if(m_DefaultRowHeight != nullptr) proc.mandatory(*m_DefaultRowHeight); + else + proc.mandatory(); if(m_WsBool != nullptr) proc.mandatory(*m_WsBool); + else + { + WsBool wsbool(is_dialog); + proc.mandatory(wsbool); + } if(m_HorizontalPageBreaks != nullptr) proc.mandatory(*m_HorizontalPageBreaks); + if(m_VerticalPageBreaks != nullptr) proc.mandatory(*m_VerticalPageBreaks); return true; From 6d6f87cae683ad5a5f02f234099e79bbb0655ef3 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 7 Apr 2025 19:41:34 +0600 Subject: [PATCH 021/114] Add worksheet substream wrting --- .../Format/Logic/Biff_records/Dimensions.cpp | 9 ++++ .../Format/Logic/Biff_records/Footer.cpp | 4 +- .../Format/Logic/Biff_records/Header.cpp | 4 +- .../Format/Logic/Biff_records/Setup.cpp | 2 +- .../Format/Logic/Biff_unions/COLUMNS.cpp | 20 +++++--- .../Format/Logic/Biff_unions/PAGESETUP.cpp | 10 ++++ .../Format/Logic/WorksheetSubstream.cpp | 47 +++++++++++++++++++ .../XlsFile/Format/Logic/WorksheetSubstream.h | 1 + 8 files changed, 87 insertions(+), 10 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.cpp index 38917528b9..80b06685e2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.cpp @@ -83,6 +83,15 @@ void Dimensions::readFields(CFRecord& record) void Dimensions::writeFields(CFRecord& record) { + if(ref_ != L"") + { + CellRangeRef rangeRef; + rangeRef.fromString(ref_); + rwMic = rangeRef.rowFirst; + colMic = rangeRef.columnFirst; + rwMac = rangeRef.rowLast; + colMac = rangeRef.columnLast; + } record << rwMic << rwMac; record << colMic << colMac; record.reserveNunBytes(2); // reserved diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.cpp index e8add7e57d..adcddc4414 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Footer.cpp @@ -37,6 +37,7 @@ namespace XLS Footer::Footer() { + ast = L""; } @@ -70,7 +71,8 @@ void Footer::readFields(CFRecord& record) void Footer::writeFields(CFRecord& record) { - record << ast; + if(ast.getSize()) + record << ast; } } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.cpp index b497a9d083..c3e96a9bca 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Header.cpp @@ -37,6 +37,7 @@ namespace XLS Header::Header() { + ast = L""; } @@ -70,7 +71,8 @@ void Header::readFields(CFRecord& record) void Header::writeFields(CFRecord& record) { - record << ast; + if(ast.getSize() > 0) + record << ast; } } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Setup.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Setup.cpp index 3cf7a01dde..a3eeef95c7 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Setup.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Setup.cpp @@ -135,7 +135,7 @@ void Setup::readFields(CFRecord& record) void Setup::writeFields(CFRecord& record) { - _UINT16 flags; + _UINT16 flags = 0; if (record.getGlobalWorkbookInfo()->Version < 0x0800) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp index f8a2d58d55..296aadafbd 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp @@ -95,14 +95,20 @@ const bool COLUMNS::loadContent(BinProcessor& proc) const bool COLUMNS::saveContent(BinProcessor& proc) { global_info_ = proc.getGlobalWorkbookInfo(); - proc.mandatory(*m_DefColWidth); - for(auto i:global_info_->sheets_info[global_info_->current_sheet - 1].customColumnsWidth) + if(m_DefColWidth != nullptr) + proc.mandatory(*m_DefColWidth); + else + proc.mandatory(); + if(global_info_ && global_info_->sheets_info.size() > global_info_->current_sheet) { - ColInfo column_info; - column_info.colFirst = i.first; - column_info.colLast = i.first; - column_info.coldx = i.second * 256; - proc.mandatory(column_info); + for(auto i:global_info_->sheets_info[global_info_->current_sheet - 1].customColumnsWidth) + { + ColInfo column_info; + column_info.colFirst = i.first; + column_info.colLast = i.first; + column_info.coldx = i.second * 256; + proc.mandatory(column_info); + } } return true; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp index 3559c041ec..7828353afe 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp @@ -172,14 +172,24 @@ const bool PAGESETUP::saveContent(BinProcessor& proc) { if(m_Header != nullptr) proc.mandatory(*m_Header); + else + proc.mandatory
(); if(m_Footer != nullptr) proc.mandatory(*m_Footer); + else + proc.mandatory