Files
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

495 lines
12 KiB
C++

/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "../../Common/Utils/simple_xml_writer.h"
#include "PropertySetStream.h"
#include "CodePageOle.h"
#include "../../XlsFile/Format/Binary/CFStream.h"
#include "../../XlsFile/Format/Auxiliary/HelpFunc.h"
#include "../../../DesktopEditor/common/SystemUtils.h"
#include "../../../OOXML/Base/Base.h"
#include "../../../OOXML/Base/Unit.h"
namespace OLEPS
{
void PropertySetStream::read(XLS::CFStreamPtr stream, bool ext)
{
if (!stream) return;
unsigned short ByteOrder = 0;
unsigned short Version = 0;
_UINT32 SystemIdentifier = 0;
_UINT32 NumPropertySets = 0;
_GUID_ Clsid = {};
*stream >> ByteOrder >> Version >> SystemIdentifier;
if (ByteOrder != 0xFFFE) //file (53).xls
return;
if (Version != 0x01 && Version != 0x00)
return;
*stream >> SystemIdentifier >> Clsid;
*stream >> NumPropertySets;
if (SystemIdentifier == NumPropertySets)
{//oops
_GUID_ Clsid2 = {};
_UINT32 reserved1 = 0, reserved2 = 0;
*stream >> Clsid2 >> reserved1 >> reserved2; // ??? ReportBuilder
*stream >> NumPropertySets;
}
if (NumPropertySets != 0x01 && NumPropertySets != 0x02)
{
NumPropertySets = 0x01;
stream->seekFromBegin(28);
}
std::vector<_UINT32> property_sets_offsets;
for (_UINT32 i = 0; i < NumPropertySets; ++i)
{
_GUID_ FMTID;
_UINT32 Offset;
*stream >> FMTID >> Offset;
if (Offset < stream->getStreamSize())
property_sets_offsets.push_back(Offset);
}
for (_UINT32 i = 0; i < property_sets_offsets.size(); ++i)
{
PropertySetPtr set = PropertySetPtr(new PropertySet(stream, property_sets_offsets[i], ext));
property_sets.push_back(set);
}
}
PropertyPtr PropertySetStream::GetProperty(unsigned int id)
{
PropertyPtr prop;
for (size_t i = 0; i < property_sets.size(); ++i)
{
prop = property_sets[i]->GetProperty(id);
if (prop)
break;
}
return prop;
}
const unsigned short PropertySetStream::GetCodePage()
{
return 0 != property_sets.size() ? property_sets[0]->GetCodePage() : 0;
}
std::wstring PropertySetStream::GetApp()
{
if (property_sets.empty()) return L"";
PropertyPtr prop;
std::wstringstream output;
CP_XML_WRITER(output)
{
CP_XML_NODE(L"Properties")
{
CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties");
CP_XML_ATTR(L"xmlns:vt", L"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
prop = GetProperty(TEMPLATE);
if ((prop) && (false == prop->IsEmpty()))
{
CP_XML_NODE(L"Template")
{
CP_XML_CONTENT(prop->toString());
}
}
prop = GetProperty(MANAGER);
if ((prop) && (false == prop->IsEmpty()))
{
CP_XML_NODE(L"Manager")
{
CP_XML_CONTENT(prop->toString());
}
}
prop = GetProperty(COMPANY);
if ((prop) && (false == prop->IsEmpty()))
{
CP_XML_NODE(L"Company")
{
CP_XML_CONTENT(prop->toString());
}
}
prop = GetProperty(PAGECOUNT);
if (prop)
{
CP_XML_NODE(L"Pages")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(WORDCOUNT);
if (prop)
{
CP_XML_NODE(L"Words")
{
CP_XML_STREAM() << prop->toString();
}
}
//prop = GetProperty(CHARCOUNT);
//if (prop)
//{
// CP_XML_NODE(L"CharactersWithSpaces")
// {
// CP_XML_STREAM() << prop->toString();
// }
//}
prop = GetProperty(CHARCOUNT);
if (prop)
{
CP_XML_NODE(L"Characters")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(PRESFORMAT);
if ((prop) && (false == prop->IsEmpty()))
{
CP_XML_NODE(L"PresentationFormat")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(LINECOUNT);
if (prop)
{
CP_XML_NODE(L"Lines")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(PARACOUNT);
if (prop)
{
CP_XML_NODE(L"Paragraphs")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(SLIDECOUNT);
if (prop)
{
CP_XML_NODE(L"Slides")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(NOTECOUNT);
if (prop)
{
CP_XML_NODE(L"Notes")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(HIDDENCOUNT);
if (prop)
{
CP_XML_NODE(L"HiddenSlides")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(MMCLIPCOUNT);
if (prop)
{
CP_XML_NODE(L"MMClips")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(SCALE);
if (prop)
{
CP_XML_NODE(L"ScaleCrop")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(HEADINGPAIR);
if (prop)
{
CP_XML_NODE(L"HeadingPairs")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(DOCPARTS);
if (prop)
{
CP_XML_NODE(L"TitlesOfParts")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(LINKBASE);
if (prop)
{
CP_XML_NODE(L"LinksUpToDate")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(CCHWITHSPACES);
if (prop)
{
CP_XML_NODE(L"CharactersWithSpaces")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(SHAREDDOC);
if (prop)
{
CP_XML_NODE(L"SharedDoc")
{
CP_XML_STREAM() << prop->toString();
}
}
// LINKBASE = 0x1014,
prop = GetProperty(HLINKS);
if (prop)
{
CP_XML_NODE(L"HLinks")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(HYPERLINKSCHANGED);
if (prop)
{
CP_XML_NODE(L"HyperlinksChanged")
{
CP_XML_STREAM() << prop->toString();
}
}
// DIGSIG = 0x1018,
CP_XML_NODE(L"Application")
{
std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName);
if (sApplication.empty())
sApplication = NSSystemUtils::gc_EnvApplicationNameDefault;
prop = GetProperty(APPNAME);
if ((prop) && (false == prop->IsEmpty()))
{
CP_XML_STREAM() << (prop->toString() + L"/" + sApplication);
}
else
{
CP_XML_STREAM() << sApplication;
#if defined(INTVER)
std::string s = VALUE2STR(INTVER);
CP_XML_STREAM() << L"/" << std::wstring(s.begin(), s.end());
#endif
}
}
prop = GetProperty(DOCVERSION);
if ((prop) && (false == prop->IsEmpty()))
{
CP_XML_NODE(L"AppVersion")
{
CP_XML_STREAM() << prop->toString();
}
}
prop = GetProperty(DOC_SECURITY);
if (prop)
{
CP_XML_NODE(L"DocSecurity")
{
CP_XML_STREAM() << prop->toString();
}
}
}
}
return output.str();
}
std::wstring PropertySetStream::GetCore()
{
if (property_sets.empty()) return L"";
std::wstringstream output;
PropertyPtr prop;
std::wstring value;
CP_XML_WRITER(output)
{
CP_XML_NODE(L"cp:coreProperties")
{
CP_XML_ATTR(L"xmlns:cp", L"http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
CP_XML_ATTR(L"xmlns:dc", L"http://purl.org/dc/elements/1.1/");
CP_XML_ATTR(L"xmlns:dcterms", L"http://purl.org/dc/terms/");
CP_XML_ATTR(L"xmlns:dcmitype", L"http://purl.org/dc/dcmitype/");
CP_XML_ATTR(L"xmlns:xsi", L"http://www.w3.org/2001/XMLSchema-instance");
prop = GetProperty(TITLE);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"dc:title")
{
CP_XML_CONTENT(value);
}
}
prop = GetProperty(SUBJECT);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"dc:subject")
{
CP_XML_CONTENT(value);
}
}
prop = GetProperty(AUTHOR);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"dc:creator")
{
CP_XML_CONTENT(value);
}
}
prop = GetProperty(KEYWORDS);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"cp:keywords")
{
CP_XML_CONTENT(value);
}
}
prop = GetProperty(COMMENTS);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"dc:description")
{
CP_XML_CONTENT(value);
}
}
prop = GetProperty(LANGUAGE);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"dc:language")
{
CP_XML_STREAM() << value;
}
}
prop = GetProperty(VERSION);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"cp:version")
{
CP_XML_STREAM() << value;
}
}
prop = GetProperty(LASTAUTHOR);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"cp:lastModifiedBy")
{
CP_XML_CONTENT(value);
}
}
prop = GetProperty(REVNUMBER);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
unsigned int val = XmlUtils::GetUInteger(value);
CP_XML_NODE(L"cp:revision")
{
CP_XML_STREAM() << val;
}
}
prop = GetProperty(CREATE_DTM);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"dcterms:created")
{
CP_XML_ATTR(L"xsi:type", L"dcterms:W3CDTF");
CP_XML_STREAM() << value;
}
}
prop = GetProperty(LASTSAVE_DTM);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"dcterms:modified")
{
CP_XML_ATTR(L"xsi:type", L"dcterms:W3CDTF");
CP_XML_STREAM() << value;
}
}
prop = GetProperty(CATEGORY);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"cp:category")
{
CP_XML_CONTENT(value);
}
}
prop = GetProperty(CONTENTSTATUS);
value = prop ? prop->toString() : L"";
if (!value.empty())
{
CP_XML_NODE(L"cp:contentStatus")
{
CP_XML_STREAM() << value;
}
}
// BYTECOUNT = 0x1004,
// LINKSDIRTY = 0x1010,
// CONTENTTYPE = 0x101A,
}
}
return output.str();
}
} // namespace OLEPS