Added a parse of the basic structure of the OFD format

This commit is contained in:
Green
2025-03-10 14:21:25 +03:00
parent e1274dadea
commit 4d23382c92
13 changed files with 706 additions and 0 deletions

93
OFDFile/OFDFile.cpp Normal file
View File

@ -0,0 +1,93 @@
#include "OFDFile.h"
#include "../OfficeUtils/src/OfficeUtils.h"
namespace OFD
{
COfdFile::COfdFile()
{}
COfdFile::~COfdFile()
{
Close();
}
void COfdFile::Close()
{
}
void COfdFile::SetTempDir(const std::wstring& wsPath)
{
m_wsTempDir = wsPath;
}
std::wstring COfdFile::GetTempDir() const
{
return m_wsTempDir;
}
bool COfdFile::Read(IFolder* pFolder)
{
if (nullptr == pFolder)
return false;
if (!m_oBase.Read(pFolder))
return false;
return false;
}
IFolder* COfdFile::CreateTempDir() const
{
if (!NSDirectory::Exists(m_wsTempDir))
NSDirectory::CreateDirectory(m_wsTempDir);
int nCounter = 0;
std::wstring wsTempFolder = m_wsTempDir + L"/OFD/";
while (NSDirectory::Exists(wsTempFolder))
{
wsTempFolder = m_wsTempDir + L"/OFD" + std::to_wstring(nCounter) + L'/';
nCounter++;
}
NSDirectory::CreateDirectory(wsTempFolder);
return new CFolderSystem(wsTempFolder);
}
bool COfdFile::LoadFromFile(const std::wstring& wsFilePath)
{
Close();
IFolder* pFolder = CreateTempDir();
if (nullptr == pFolder)
return false;
COfficeUtils oUtils(NULL);
if (S_OK != oUtils.ExtractToDirectory(wsFilePath, pFolder->getFullFilePath(L""), NULL, 0))
return false;
bool bResult = Read(pFolder);
if (!bResult)
{
pFolder->removeDirectory(L"");
delete pFolder;
}
return false;
}
bool COfdFile::SaveToFile(const std::wstring& wsFilePath)
{
return false;
}
bool COfdFile::SaveToDir(const std::wstring& wsDir)
{
return false;
}
}

35
OFDFile/OFDFile.pro Normal file
View File

@ -0,0 +1,35 @@
QT -= core gui
VERSION = 1.0.0.1
TARGET = OFDFile
TEMPLATE = lib
CONFIG += shared
CONFIG += plugin
CORE_ROOT_DIR = $$PWD/..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri)
DEFINES += OFD_USE_DYNAMIC_LIBRARY
ADD_DEPENDENCY(graphics, kernel, UnicodeConverter)
HEADERS += \
OFDFile.h \
src/Base.h \
src/Document.h \
src/Page.h \
src/PublicRes.h
SOURCES += \
OFDFile.cpp \
src/Base.cpp \
src/Document.cpp \
src/Page.cpp \
src/PublicRes.cpp
HEADERS += $$CORE_ROOT_DIR/OOXML/Base/Unit.h
SOURCES += $$CORE_ROOT_DIR/OOXML/Base/Unit.cpp

41
OFDFile/OfdFile.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef OFDFILE_H
#define OFDFILE_H
#include "../OfficeUtils/src/ZipFolder.h"
#include "src/Base.h"
#ifndef OFD_USE_DYNAMIC_LIBRARY
#define OFD_DECL_EXPORT
#else
#include "../DesktopEditor/common/base_export.h"
#define OFD_DECL_EXPORT Q_DECL_EXPORT
#endif
namespace OFD
{
class OFD_DECL_EXPORT COfdFile
{
std::wstring m_wsTempDir;
CBase m_oBase;
bool Read(IFolder* pFolder);
IFolder* CreateTempDir() const;
public:
COfdFile();
~COfdFile();
void Close();
void SetTempDir(const std::wstring& wsPath);
std::wstring GetTempDir() const;
bool LoadFromFile(const std::wstring& wsFilePath);
bool SaveToFile(const std::wstring& wsFilePath);
bool SaveToDir(const std::wstring& wsDir);
};
}
#endif // OFDFILE_H

134
OFDFile/src/Base.cpp Normal file
View File

@ -0,0 +1,134 @@
#include "Base.h"
namespace OFD
{
#define IF_CHECK_NODE(node_name, varible_name)\
if (node_name == wsNodeName)\
varible_name = oLiteReader.GetText2()
#define ELSE_IF_CHECK_NODE(node_name, varible_name)\
else if (node_name == wsNodeName)\
varible_name = oLiteReader.GetText2()
EDocUsege GetDocUsage(const std::wstring& wsValue)
{
if (L"EBook" == wsValue)
return EDocUsege::EBook;
else if (L"ENewsPaper" == wsValue)
return EDocUsege::ENewsPaper;
else if (L"EMagnize" == wsValue)
return EDocUsege::EMagzine;
else
return EDocUsege::Normal;
}
CDocInfo::CDocInfo()
: m_eDocUsage(EDocUsege::Normal)
{}
bool CDocInfo::Read(XmlUtils::CXmlLiteReader& oLiteReader)
{
if (L"ofd:DocInfo" != oLiteReader.GetName())
return false;
const int nDepth = oLiteReader.GetDepth();
std::wstring wsNodeName;
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
wsNodeName = oLiteReader.GetName();
IF_CHECK_NODE(L"ofd:DocID", m_wsDocId);
ELSE_IF_CHECK_NODE(L"ofd:Title", m_wsTitle);
ELSE_IF_CHECK_NODE(L"ofd:Author", m_wsAuthor);
ELSE_IF_CHECK_NODE(L"ofd:Subject", m_wsSubject);
ELSE_IF_CHECK_NODE(L"ofd:Abstruct", m_wsAbstact);
ELSE_IF_CHECK_NODE(L"ofd:CreationDate", m_wsCreationDate);
ELSE_IF_CHECK_NODE(L"ofd:ModDate", m_wsModDate);
ELSE_IF_CHECK_NODE(L"ofd:Cover", m_wsCover);
ELSE_IF_CHECK_NODE(L"ofd:Creator", m_wsCreator);
ELSE_IF_CHECK_NODE(L"ofd:CreatorVersion", m_wsCreatorVersion);
else if (L"ofd:DocUsage" == wsNodeName)
m_eDocUsage = GetDocUsage(oLiteReader.GetText2());
}
return true;
}
CDocBody::CDocBody()
{
}
CDocBody* CDocBody::Read(XmlUtils::CXmlLiteReader& oLiteReader, IFolder* pFolder)
{
if (L"ofd:DocBody" != oLiteReader.GetName())
return nullptr;
const int nDepth = oLiteReader.GetDepth();
std::wstring wsNodeName;
CDocBody *pDocBody = new CDocBody();
if (nullptr == pDocBody)
return nullptr;
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
wsNodeName = oLiteReader.GetName();
if (L"ofd:DocInfo" == wsNodeName)
{
if (!pDocBody->m_oDocInfo.Read(oLiteReader))
{
delete pDocBody;
return nullptr;
}
}
else if (L"ofd:DocRoot" == wsNodeName)
{
const std::wstring wsPath = NSSystemPath::ShortenPath(oLiteReader.GetText2());
if (!wsPath.empty() && L'.' != wsPath.front())
pDocBody->m_oDocument.Read(pFolder->getFullFilePath(wsPath));
}
ELSE_IF_CHECK_NODE(L"ofd:Signatures", pDocBody->m_wsSignature);
}
return pDocBody;
}
CBase::CBase()
{}
CBase::~CBase()
{
for (CDocBody* pDocBody : m_arDocBodies)
RELEASEOBJECT(pDocBody);
}
bool CBase::Read(IFolder* pFolder)
{
if (nullptr == pFolder || !pFolder->existsXml(L"OFD.xml"))
return false;
XmlUtils::CXmlLiteReader oLiteReader;
if (!oLiteReader.FromFile(pFolder->getFullFilePath(L"OFD.xml")) || !oLiteReader.ReadNextNode() || L"ofd:OFD" != oLiteReader.GetName())
return false;
const int nDepth = oLiteReader.GetDepth();
CDocBody* pDocBody = nullptr;
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
pDocBody = CDocBody::Read(oLiteReader, pFolder);
if (nullptr != pDocBody)
m_arDocBodies.push_back(pDocBody);
}
return false;
}
}

73
OFDFile/src/Base.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef BASE_H
#define BASE_H
#include "../../OfficeUtils/src/ZipFolder.h"
#include "Document.h"
namespace OFD
{
enum class EDocUsege
{
Normal,
EBook,
ENewsPaper,
EMagzine
};
class CDocInfo
{
std::wstring m_wsDocId;
std::wstring m_wsTitle;
std::wstring m_wsAuthor;
std::wstring m_wsSubject;
std::wstring m_wsAbstact;
std::wstring m_wsCreationDate;
std::wstring m_wsModDate;
EDocUsege m_eDocUsage;
std::wstring m_wsCover;
std::vector<std::wstring> m_arKeywords;
std::wstring m_wsCreator;
std::wstring m_wsCreatorVersion;
std::vector<std::wstring> m_arCustomData;
public:
CDocInfo();
bool Read(XmlUtils::CXmlLiteReader& oLiteReader);
};
class CDocBody
{
CDocInfo m_oDocInfo;
CDocument m_oDocument;
// std::wstring m_wsPathToDocRoot;
// std::wstring m_wsVersions;
std::wstring m_wsSignature;
public:
CDocBody();
static CDocBody* Read(XmlUtils::CXmlLiteReader& oLiteReader, IFolder* pFolder);
};
class CBase
{
std::vector<CDocBody*> m_arDocBodies;
public:
CBase();
~CBase();
bool Read(IFolder* pFolder);
std::wstring GetDocId() const;
std::wstring GetCreationDate() const;
std::wstring GetCreator() const;
std::wstring GetCreatorVersion() const;
std::wstring GetpathToDocRoot() const;
};
}
#endif // BASE_H

166
OFDFile/src/Document.cpp Normal file
View File

@ -0,0 +1,166 @@
#include "Document.h"
#include "../../DesktopEditor/common/StringExt.h"
#include "../../OOXML/Base/Unit.h"
#include <iostream>
namespace OFD
{
#define OFD_EPSILON 0.0001
CPageArea::CPageArea()
{}
bool CPageArea::Read(XmlUtils::CXmlLiteReader& oLiteReader)
{
if (L"ofd:PageArea" != oLiteReader.GetName())
return false;
const int nDepth = oLiteReader.GetDepth();
std::wstring wsNodeName;
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
wsNodeName = oLiteReader.GetName();
if (L"ofd:PhysicalBox" == wsNodeName)
m_oPhysicalBox.Read(oLiteReader.GetText2());
else if (L"ofd:ApplicationBox" == wsNodeName)
m_oApplicationBox.Read(oLiteReader.GetText2());
else if (L"ofd:ContentBox" == wsNodeName)
m_oContentBox.Read(oLiteReader.GetText2());
else if (L"ofd:BleedBox" == wsNodeName)
m_oBleedBox.Read(oLiteReader.GetText2());
}
return true;
}
CCommonData::CCommonData()
: m_unMaxUnitID(0)
{}
bool CCommonData::Read(XmlUtils::CXmlLiteReader& oLiteReader)
{
if (L"ofd:CommonData" != oLiteReader.GetName())
return false;
const int nDepth = oLiteReader.GetDepth();
std::wstring wsNodeName;
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
wsNodeName = oLiteReader.GetName();
if (L"ofd:PageArea" == wsNodeName)
m_oPageArea.Read(oLiteReader);
else if (L"ofd:PublicRes" == wsNodeName)
{
// m_oPublicRes.Read();
}
else if (L"ofd:MaxUnitID" == wsNodeName)
m_unMaxUnitID = XmlUtils::GetUInteger(oLiteReader.GetText2());
// else if (L"ofd:DocumentRes" == wsNodeName)
// else if (L"ofd:TemplatePage" == wsNodeName)
// else if (L"ofd:DefaultCS" == wsNodeName)
}
return true;
}
CDocument::CDocument()
{}
CDocument::~CDocument()
{
for (std::pair<int, CPage*> oElement : m_mPages)
delete oElement.second;
}
bool CDocument::Empty() const
{
return m_mPages.empty();
}
bool CDocument::Read(const std::wstring& wsFilePath)
{
if (wsFilePath.empty())
return false;
XmlUtils::CXmlLiteReader oLiteReader;
if (!oLiteReader.FromFile(wsFilePath) || !oLiteReader.ReadNextNode() || L"ofd:Document" != oLiteReader.GetName())
return false;
const int nDepth = oLiteReader.GetDepth();
std::wstring wsNodeName;
while (oLiteReader.ReadNextSiblingNode(nDepth))
{
wsNodeName = oLiteReader.GetName();
if (L"ofd:CommonData" == wsNodeName)
m_oCommonData.Read(oLiteReader);
else if (L"ofd:Pages" == wsNodeName)
{
const int nPagesDepth = oLiteReader.GetDepth();
int nID = -1;
std::wstring wsBaseLoc;
while (oLiteReader.ReadNextSiblingNode(nPagesDepth))
{
if (L"ofd:Page" != oLiteReader.GetName() || 2 > oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute())
continue;
do
{
if (L"ID" == oLiteReader.GetName())
nID = XmlUtils::GetUInteger(oLiteReader.GetText());
else if (L"BaseLoc" == oLiteReader.GetName())
wsBaseLoc = oLiteReader.GetText();
}while (oLiteReader.MoveToNextAttribute());
if (wsBaseLoc.empty())
continue;
if (-1 == nID)
nID = m_mPages.size() + 1;
CPage* pPage = CPage::Read(NSSystemPath::Combine(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc));
if (nullptr != pPage)
m_mPages.insert(std::make_pair(nID, pPage));
wsBaseLoc.clear();
oLiteReader.MoveToElement();
}
}
}
return false;
}
TBox::TBox()
: m_dX(0.), m_dY(0.), m_dWidth(0.), m_dHeight(0.)
{}
bool TBox::Empty() const
{
return m_dWidth < OFD_EPSILON || m_dHeight < OFD_EPSILON;
}
bool TBox::Read(const std::wstring& wsValue)
{
const std::vector<std::wstring> arValues{NSStringExt::Split(wsValue, L' ')};
if (4 > arValues.size())
return false;
m_dX = XmlUtils::GetDouble(arValues[0]);
m_dY = XmlUtils::GetDouble(arValues[1]);
m_dWidth = XmlUtils::GetDouble(arValues[2]);
m_dHeight = XmlUtils::GetDouble(arValues[3]);
return true;
}
}

60
OFDFile/src/Document.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef DOCUMENT_H
#define DOCUMENT_H
#include "Page.h"
#include "PublicRes.h"
namespace OFD
{
struct TBox
{
double m_dX;
double m_dY;
double m_dWidth;
double m_dHeight;
TBox();
bool Empty() const;
bool Read(const std::wstring& wsValue);
};
class CPageArea
{
TBox m_oPhysicalBox;
TBox m_oApplicationBox;
TBox m_oContentBox;
TBox m_oBleedBox;
public:
CPageArea();
bool Read(XmlUtils::CXmlLiteReader& oLiteReader);
};
class CCommonData
{
unsigned int m_unMaxUnitID;
CPageArea m_oPageArea;
CPublicRes m_oPublicRes;
public:
CCommonData();
bool Read(XmlUtils::CXmlLiteReader& oLiteReader);
};
class CDocument
{
CCommonData m_oCommonData;
std::map<unsigned int, CPage*> m_mPages;
public:
CDocument();
~CDocument();
bool Empty() const;
bool Read(const std::wstring& wsFilePath);
};
}
#endif // DOCUMENT_H

17
OFDFile/src/Page.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "Page.h"
namespace OFD
{
CPage::CPage()
{
}
CPage* CPage::Read(const std::wstring& wsFilePath)
{
if (wsFilePath.empty())
return nullptr;
return nullptr;
}
}

17
OFDFile/src/Page.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef PAGE_H
#define PAGE_H
#include "../../OfficeUtils/src/ZipFolder.h"
namespace OFD
{
class CPage
{
public:
CPage();
static CPage* Read(const std::wstring& wsFilePath);
};
}
#endif // PAGE_H

17
OFDFile/src/PublicRes.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "PublicRes.h"
namespace OFD
{
CPublicRes::CPublicRes()
{
}
bool CPublicRes::Read(IFolder* pFolder)
{
if (nullptr == pFolder)
return false;
return false;
}
}

17
OFDFile/src/PublicRes.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef PUBLICRES_H
#define PUBLICRES_H
#include "../../OfficeUtils/src/ZipFolder.h"
namespace OFD
{
class CPublicRes
{
public:
CPublicRes();
bool Read(IFolder* pFolder);
};
}
#endif // PUBLICRES_H

16
OFDFile/test/main.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "../OfdFile.h"
#include <iostream>
int main()
{
OFD::COfdFile oOfdFile;
oOfdFile.SetTempDir(L"temp");
if (oOfdFile.LoadFromFile(L"YOUR_PATH"))
std::cout << "GOOD" << std::endl;
else
std::cout << "BAD" << std::endl;
return 0;
}

20
OFDFile/test/test.pro Normal file
View File

@ -0,0 +1,20 @@
QT -= core
QT -= gui
TARGET = test
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
DEFINES += OFD_USE_DYNAMIC_LIBRARY
SOURCES += main.cpp
CORE_ROOT_DIR = $$PWD/../../
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(kernel, UnicodeConverter, OFDFile)
DESTDIR = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX