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

316 lines
9.4 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 "Rels.h"
namespace OOX
{
namespace Rels
{
CRelationShip::CRelationShip()
{
}
CRelationShip::CRelationShip(const OOX::RId& rId, const std::wstring& sType, const OOX::CPath& oFilePath, bool bExternal) : m_rId(rId), m_oTarget(oFilePath), m_sType(sType)
{
XmlUtils::replace_all(m_oTarget.m_strFilename, L" ", L"_");
if (bExternal)
{
m_sMode = L"External";
}
}
CRelationShip::CRelationShip(const OOX::RId& rId, const smart_ptr<External> pExternal) : m_rId(rId)
{
m_sMode = new std::wstring(L"External" );
if (pExternal.IsInit())
{
m_oTarget = pExternal->Uri();
m_sType = pExternal->type().RelationType();
}
}
CRelationShip::~CRelationShip()
{
}
void CRelationShip::fromXML(XmlUtils::CXmlLiteReader& oReader)
{
ReadAttributes( oReader );
if ( !oReader.IsEmptyNode() )
oReader.ReadTillEnd();
}
void CRelationShip::fromXML(XmlUtils::CXmlNode& oNode)
{
XmlMacroReadAttributeBase( oNode, L"Id", m_rId );
XmlMacroReadAttributeBase( oNode, L"Target", m_oTarget );
XmlMacroReadAttributeBase( oNode, L"Type", m_sType );
XmlMacroReadAttributeBase( oNode, L"TargetMode", m_sMode );
}
std::wstring CRelationShip::toXML() const
{
XmlUtils::CAttribute oAttr;
oAttr.Write(L"Id", m_rId.ToString() );
oAttr.Write(L"Type", m_sType );
std::wstring sTarget = m_oTarget.m_strFilename;
if (false == IsExternal())
XmlUtils::replace_all(sTarget,L"\\",L"/");
sTarget = XmlUtils::EncodeXmlString(sTarget);
oAttr.Write(L"Target", sTarget);
if(m_sMode.IsInit())
oAttr.Write(L"TargetMode", m_sMode.get() );
return XmlUtils::CreateNode(L"Relationship", oAttr );
}
EElementType CRelationShip::getType() const
{
return OOX::et_Relationship;
}
void CRelationShip::ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
std::wstring sTempTarget;
WritingElement_ReadAttributes_Start( oReader )
WritingElement_ReadAttributes_Read_if ( oReader,L"Id", m_rId )
WritingElement_ReadAttributes_Read_else_if( oReader,L"Target", sTempTarget )
WritingElement_ReadAttributes_Read_else_if( oReader,L"Type", m_sType )
WritingElement_ReadAttributes_Read_else_if( oReader,L"TargetMode", m_sMode )
WritingElement_ReadAttributes_End( oReader )
//External rels не нормализуем, иначе искажаются пути в гиперссылках.
if(IsExternal())
m_oTarget.SetName(sTempTarget, false);
else
m_oTarget.SetName(sTempTarget, true);
}
const std::wstring CRelationShip::Type() const
{
return m_sType;
}
const CPath CRelationShip::Filename() const
{
return m_oTarget;
}
const CPath CRelationShip::Target() const
{
return m_oTarget;
}
const bool CRelationShip::IsExternal()const
{
if ( !m_sMode.IsInit() )
return false;
return ( *m_sMode == L"External");
}
const RId CRelationShip::rId() const
{
return m_rId;
}
} // namespace Rels
CRels::CRels()
{
}
CRels::CRels(const CPath& oFilePath)
{
Read( oFilePath );
}
CRels::~CRels()
{
for (size_t i = 0; i < m_arRelations.size(); ++i)
{
if ( m_arRelations[i] ) delete m_arRelations[i];
}
m_arRelations.clear();
m_mapRelations.clear();
}
void CRels::Read (const CPath& oFilePath)
{
CPath oRelsPath = CreateFileName( oFilePath );
XmlUtils::CXmlLiteReader oReader;
if ( !oReader.FromFile( oRelsPath.GetPath() ) )
return;
if ( !oReader.ReadNextNode() )
return;
std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName());
if (L"Relationships" == sName )
{
if ( !oReader.IsEmptyNode() )
{
int nRelationshipsDepth = oReader.GetDepth();
while ( oReader.ReadNextSiblingNode( nRelationshipsDepth ) )
{
sName = XmlUtils::GetNameNoNS(oReader.GetName());
if (L"Relationship" == sName )
{
OOX::Rels::CRelationShip *pRel = new OOX::Rels::CRelationShip();
*pRel = oReader;
if (pRel)
{
std::wstring rid = pRel->rId().get();
m_arRelations.push_back(pRel);
m_mapRelations.insert(std::make_pair( rid, pRel) );
}
}
}
}
}
}
void CRels::Write(const CPath& oFilePath) const
{
if ( m_mapRelations.empty() ) return;
CPath oFile = CreateFileName( oFilePath );
CSystemUtility::CreateDirectories( oFile.GetDirectory() );
XmlUtils::CXmlWriter oWriter;
oWriter.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
oWriter.WriteNodeBegin(L"Relationships", true );
oWriter.WriteAttribute(L"xmlns",L"http://schemas.openxmlformats.org/package/2006/relationships" );
oWriter.WriteNodeEnd(L"Relationships", true, false );
for (size_t i = 0; i < m_arRelations.size(); ++i)
{
if ( m_arRelations[i] )
oWriter.WriteString( m_arRelations[i]->toXML() );
}
oWriter.WriteNodeEnd(L"Relationships");
NSFile::CFileBinary::SaveToFile(oFile.GetPath(), oWriter.GetXmlString());
}
void CRels::Registration(const RId& rId, const std::wstring& oRelationShipType, const CPath& oPath, bool bExternal)
{
if (oRelationShipType.empty()) return;
std::wstring strFileName = oPath.m_strFilename;
std::wstring strDir = oPath.GetDirectory() + L"";
Rels::CRelationShip* pRel = NULL;
if (L"" == oPath.GetExtention())
{
if (oRelationShipType == L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject")
{
strFileName += (strFileName.empty() ? L"" : L".bin");
pRel = new Rels::CRelationShip(rId, oRelationShipType, strDir + strFileName, bExternal);
}
else if (oRelationShipType == L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image")
{
strFileName += L".wmf";
pRel = new Rels::CRelationShip(rId, oRelationShipType, strDir + strFileName, bExternal);
}
}
else
{
pRel = new Rels::CRelationShip(rId, oRelationShipType, oPath.GetPath(), bExternal);
}
if (pRel)
{
m_arRelations.push_back(pRel);
m_mapRelations.insert(std::make_pair(rId.get(), pRel));
}
}
void CRels::Registration(const RId& rId, const FileType& oType, const CPath& oPath, bool bExternal)
{
if( FileTypes::Unknown == oType ) return;
std::wstring strFileName = oPath.m_strFilename;
std::wstring strDir = oPath.GetDirectory() +L"";
Rels::CRelationShip* pRel = NULL;
if ( L"" == oPath.GetExtention() )
{
if ( oType.RelationType() == L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" )
{
strFileName += (strFileName.empty() ? L"" : L".bin");
pRel = new Rels::CRelationShip( rId, oType.RelationType(), strDir + strFileName, bExternal );
}
else if ( oType.RelationType() == L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" )
{
strFileName += L".wmf" ;
pRel = new Rels::CRelationShip( rId, oType.RelationType(), strDir + strFileName, bExternal );
}
}
else
{
pRel = new Rels::CRelationShip( rId, oType.RelationType(), oPath.GetPath(), bExternal);
}
if (pRel)
{
m_arRelations.push_back(pRel);
m_mapRelations.insert( std::make_pair( rId.get(), pRel));
}
}
void CRels::Registration(const RId& rId, const smart_ptr<External> pExternal)
{
Rels::CRelationShip* pRel = new Rels::CRelationShip( rId, pExternal );
m_arRelations.push_back(pRel);
m_mapRelations.insert( std::make_pair( rId.get(), pRel) );
}
void CRels::GetRel(const RId& rId, Rels::CRelationShip** ppRelationShip)
{
(*ppRelationShip) = NULL;
boost::unordered_map<std::wstring, Rels::CRelationShip*>::iterator pFind = m_mapRelations.find(rId.get());
if (pFind != m_mapRelations.end())
{
(*ppRelationShip) = pFind->second;
}
}
const CPath CRels::CreateFileName(const CPath& oFilePath) const
{
std::wstring strTemp = oFilePath.GetDirectory() + FILE_SEPARATOR_STR +L"_rels" + FILE_SEPARATOR_STR;
if (L"" == oFilePath.GetFilename() ) strTemp +=L".rels";
else strTemp += ( oFilePath.GetFilename() +L".rels" );
CPath pathTemp = strTemp;
return pathTemp.GetPath();
}
} // namespace OOX