Fixed bugs in reading hwp format and added test example

This commit is contained in:
Green
2024-12-18 15:13:43 +03:00
parent 328e379ec2
commit 4a110d68c1
43 changed files with 505 additions and 324 deletions

28
HwpFile/HWPFile.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "HWPFile.h"
#include "HwpDoc/HWPFile_Private.h"
#include "../DesktopEditor/common/File.h"
CHWPFile::CHWPFile(const std::wstring& wsFileName)
: m_pInternal(new HWP::CHWPFile_Private(wsFileName))
{}
CHWPFile::~CHWPFile()
{
if (nullptr != m_pInternal)
delete m_pInternal;
}
bool CHWPFile::Open()
{
if (nullptr == m_pInternal)
return false;
return m_pInternal->Open();
}
void CHWPFile::Close()
{
if (nullptr != m_pInternal)
m_pInternal->Close();
}

25
HwpFile/HWPFile.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef HWPFILE_H
#define HWPFILE_H
#include <string>
#ifndef HWPFILE_USE_DYNAMIC_LIBRARY
#define HWP_FILE_DECL_EXPORT
#else
#include "../../DesktopEditor/common/base_export.h"
#define HWP_FILE_DECL_EXPORT Q_DECL_EXPORT
#endif
namespace HWP { class CHWPFile_Private; }
class HWP_FILE_DECL_EXPORT CHWPFile
{
HWP::CHWPFile_Private *m_pInternal;
public:
CHWPFile(const std::wstring& wsFileName);
~CHWPFile();
bool Open();
void Close();
};
#endif // HWPFILE_H

View File

@ -14,7 +14,10 @@ include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(kernel, UnicodeConverter)
DEFINES += HWPFILE_USE_DYNAMIC_LIBRARY
SOURCES += \
HWPFile.cpp \
HwpDoc/HWPDocInfo.cpp \
HwpDoc/HWPElements/HWPRecord.cpp \
HwpDoc/HWPElements/HWPRecordBinData.cpp \
@ -34,7 +37,7 @@ SOURCES += \
HwpDoc/HWPElements/HWPRecordParaText.cpp \
HwpDoc/HWPElements/HWPRecordStyle.cpp \
HwpDoc/HWPElements/HwpRecordTabDef.cpp \
HwpDoc/HWPFile.cpp \
HwpDoc/HWPFile_Private.cpp \
HwpDoc/HWPSection.cpp \
HwpDoc/HWPStream.cpp \
HwpDoc/HwpFileHeader.cpp \
@ -80,6 +83,7 @@ SOURCES += \
HwpDoc/Section/PageBorderFill.cpp
HEADERS += \
HWPFile.h \
HwpDoc/Common.h \
HwpDoc/Errors.h \
HwpDoc/HWPDocInfo.h \
@ -104,7 +108,7 @@ HEADERS += \
HwpDoc/HWPElements/HWPType.h \
HwpDoc/HWPElements/HwpRecordTabDef.h \
HwpDoc/HWPElements/HwpRecordTypes.h \
HwpDoc/HWPFile.h \
HwpDoc/HWPFile_Private.h \
HwpDoc/HWPSection.h \
HwpDoc/HWPStream.h \
HwpDoc/HanType.h \

View File

@ -8,12 +8,14 @@
namespace HWP
{
typedef char16_t CHAR;
typedef std::string STRING;
typedef std::wstring STRING;
typedef char BYTE;
#define LIST std::list
#define VECTOR std::vector
#define TO_STRING(val) std::to_wstring(val)
#define CLEAR_ARRAY(type, array) \
for (type* pValue : array) \
if (nullptr != pValue) \

View File

@ -14,7 +14,7 @@ CHWPDocInfo::CHWPDocInfo(EHanType eHanType)
// : m_eHanType(EHanType::HWPX), m_pParentHWPX(pHWPXFile)
// {}
CHWPDocInfo::CHWPDocInfo(CHWPFile* pHWPFile)
CHWPDocInfo::CHWPDocInfo(CHWPFile_Private* pHWPFile)
: m_eHanType(EHanType::HWP), m_pParentHWP(pHWPFile)
{}
@ -51,7 +51,7 @@ bool CHWPDocInfo::Parse(CHWPStream& oBuffer, int nVersion)
{
int nOff = 0;
while (nOff < oBuffer.GetLength())
while (nOff < oBuffer.GetSize())
{
int nHeader = ((oBuffer[nOff + 3] << 24) & 0xFF000000) | ((oBuffer[nOff + 2] << 16) & 0xFF0000) | ((oBuffer[nOff + 1] << 8) & 0xFF00) | (oBuffer[nOff] & 0xFF);
int nTagNum = nHeader & 0x3FF;

View File

@ -10,12 +10,12 @@
namespace HWP
{
class CHWPFile;
class CHWPFile_Private;
class CHWPDocInfo
{
EHanType m_eHanType;
// CHWPXFile *m_pParentHWPX;
CHWPFile *m_pParentHWP;
CHWPFile_Private *m_pParentHWP;
std::list<CHWPRecord*> m_lRecords;
std::map<STRING, CHWPRecord*> m_mBinDatas;
@ -33,7 +33,7 @@ class CHWPDocInfo
public:
CHWPDocInfo(EHanType eHanType);
// CHWPDocInfo(CHWPXFile* pHWPXFile);
CHWPDocInfo(CHWPFile* pHWPFile);
CHWPDocInfo(CHWPFile_Private* pHWPFile);
~CHWPDocInfo();

View File

@ -117,7 +117,7 @@ CFill::CFill(CHWPStream& oBuffer, int nOff, int nSize)
short shBinTemp;
oBuffer.ReadShort(shBinTemp);
m_sBinItemID = std::to_string(shBinTemp - 1);
m_sBinItemID = TO_STRING(shBinTemp - 1);
}
int nMoreSize;

View File

@ -1,7 +1,7 @@
#ifndef HWPRECORDBORDERFILL_H
#define HWPRECORDBORDERFILL_H
#include "HwpDoc/HWPDocInfo.h"
#include "../HWPDocInfo.h"
#include "HwpRecordTypes.h"
#include "../HWPStream.h"
#include <vector>

View File

@ -40,7 +40,7 @@ CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, int nTagNum, int nLeve
short shValue;
oBuffer.ReadShort(shValue);
m_sBinItemRefID = std::to_string(shValue);
m_sBinItemRefID = TO_STRING(shValue);
}
}
}

View File

@ -24,36 +24,36 @@ CCtrl* CHWPRecordCtrlHeader::Parse(int nTagNum, int nLevel, int nSize, CHWPStrea
oBuffer.SavePosition();
STRING sCtrlID;
oBuffer.ReadString(sCtrlID, 4); //TODO::StandardCharsets.US_ASCII
oBuffer.ReadString(sCtrlID, 4, EStringCharacter::ASCII); //TODO::StandardCharsets.US_ASCII
CCtrl* pCtrl = nullptr;
if ("dces" == sCtrlID)
if (L"dces" == sCtrlID)
pCtrl = new CCtrlSectionDef(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
else if ("dloc" == sCtrlID)
else if (L"dloc" == sCtrlID)
pCtrl = new CCtrlColumnDef(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
else if ("daeh" == sCtrlID)
else if (L"daeh" == sCtrlID)
pCtrl = new CCtrlHeadFoot(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion, true);
else if ("toof" == sCtrlID)
else if (L"toof" == sCtrlID)
pCtrl = new CCtrlHeadFoot(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion, false);
else if (" nf" == sCtrlID || " ne" == sCtrlID)
else if (L" nf" == sCtrlID || L" ne" == sCtrlID)
pCtrl = new CCtrlNote(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
else if (" lbt" == sCtrlID)
else if (L" lbt" == sCtrlID)
pCtrl = new CCtrlTable(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
else if ("onta" == sCtrlID)
else if (L"onta" == sCtrlID)
pCtrl = new CCtrlAutoNumber(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
else if ("onwn" == sCtrlID)
else if (L"onwn" == sCtrlID)
pCtrl = new CCtrlNewNumber(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
else if (" osg" == sCtrlID)
else if (L" osg" == sCtrlID)
pCtrl = new CCtrlGeneralShape(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
else if ("deqe" == sCtrlID)
else if (L"deqe" == sCtrlID)
pCtrl = new CCtrlEqEdit(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
else if ("dhgp" == sCtrlID)
else if (L"dhgp" == sCtrlID)
{
int nTempSize = nSize - oBuffer.GetDistanceToLastPos();
oBuffer.Skip(nTempSize);
}
else if ("cot%" == sCtrlID)
else if (L"cot%" == sCtrlID)
{
// Когда содержимое считывается как UTF_16LE, следующее содержимое остается тем же самым
// ¥TableOfContents:set:140:ContentsMake:uint:17 ContentsStyles:wstring:0: ContentsLevel:int:5 ContentsAutoTabRight:int:0 ContentsLeader:int:3 ContentsHyperlink:bool:1
@ -61,36 +61,36 @@ CCtrl* CHWPRecordCtrlHeader::Parse(int nTagNum, int nLevel, int nSize, CHWPStrea
int nTempSize = nSize - oBuffer.GetDistanceToLastPos();
oBuffer.Skip(nTempSize);
}
else if ("klc%" == sCtrlID)
else if (L"klc%" == sCtrlID)
{
pCtrl = new CCtrlClick(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
pCtrl->SetFullFilled();
}
else if ("mrof" == sCtrlID)
else if (L"mrof" == sCtrlID)
{
pCtrl = new CCtrlForm(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
pCtrl->SetFullFilled();
}
else if ("pngp" == sCtrlID)
else if (L"pngp" == sCtrlID)
{
pCtrl = new CCtrlPageNumPos(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
pCtrl->SetFullFilled();
}
else if ("klh%" == sCtrlID || // hyperlink
"frx%" == sCtrlID || // FIELD_CROSSREF
"knu%" == sCtrlID || // FIELD_UNKNOWN
"etd%" == sCtrlID || // FIELD_DATE
"tdd%" == sCtrlID || // FIELD_DOCDATE
"tap%" == sCtrlID || // FIELD_PATH
"kmb%" == sCtrlID || // FIELD_BOOKMARK
"gmm%" == sCtrlID || // FIELD_MAILMERGE
"umf%" == sCtrlID || // FIELD_FORMULA
"mxdi" == sCtrlID || // ???
"mkob" == sCtrlID || // ???
"spct" == sCtrlID || // ???
"tmct" == sCtrlID || // ???
"tcgp" == sCtrlID || // ???
"tudt" == sCtrlID) // ???
else if (L"klh%" == sCtrlID || // hyperlink
L"frx%" == sCtrlID || // FIELD_CROSSREF
L"knu%" == sCtrlID || // FIELD_UNKNOWN
L"etd%" == sCtrlID || // FIELD_DATE
L"tdd%" == sCtrlID || // FIELD_DOCDATE
L"tap%" == sCtrlID || // FIELD_PATH
L"kmb%" == sCtrlID || // FIELD_BOOKMARK
L"gmm%" == sCtrlID || // FIELD_MAILMERGE
L"umf%" == sCtrlID || // FIELD_FORMULA
L"mxdi" == sCtrlID || // ???
L"mkob" == sCtrlID || // ???
L"spct" == sCtrlID || // ???
L"tmct" == sCtrlID || // ???
L"tcgp" == sCtrlID || // ???
L"tudt" == sCtrlID) // ???
{
int nTempSize = nSize - oBuffer.GetDistanceToLastPos();
oBuffer.Skip(nTempSize);

View File

@ -24,7 +24,7 @@ CHWPRecordFaceName::CHWPRecordFaceName(CHWPDocInfo& oDocInfo, int nTagNum, int n
m_bAttrExists = CHECK_FLAG(chDataBits, 0x40);
m_bSubstExists = CHECK_FLAG(chDataBits, 0x80);
oBuffer.ReadString(m_sFaceName);
oBuffer.ReadString(m_sFaceName, EStringCharacter::UTF16);
if (m_bSubstExists)
{
@ -32,7 +32,7 @@ CHWPRecordFaceName::CHWPRecordFaceName(CHWPDocInfo& oDocInfo, int nTagNum, int n
oBuffer.ReadByte(chSubsType);
m_eSubstType = GetAltType(chSubsType & 0x0F);
oBuffer.ReadString(m_sSubstFace);
oBuffer.ReadString(m_sSubstFace, EStringCharacter::UTF16);
}
if (m_bAttrExists)
@ -50,6 +50,6 @@ CHWPRecordFaceName::CHWPRecordFaceName(CHWPDocInfo& oDocInfo, int nTagNum, int n
}
if (m_bBasicFaceExists)
oBuffer.ReadString(m_sBasicFaceName);
oBuffer.ReadString(m_sBasicFaceName, EStringCharacter::UTF16);
}
}

View File

@ -14,7 +14,7 @@ int CHWPRecordFormObject::ParseCtrl(CCtrlForm& oForm, int nSize, CHWPStream& oBu
oBuffer.Skip(4); // tbp+
oBuffer.Skip(4); // Длина строки?
oBuffer.ReadString(m_sFormStr);
oBuffer.ReadString(m_sFormStr, EStringCharacter::UTF16);
return oBuffer.GetDistanceToLastPos();
}

View File

@ -20,7 +20,7 @@ CHWPRecordNumbering::CHWPRecordNumbering(CHWPDocInfo& oDocInfo, int nTagNum, int
oBuffer.ReadShort(m_arNumbering[nIndex].m_shWidthAdjust);
oBuffer.ReadShort(m_arNumbering[nIndex].m_shTextOffset);
oBuffer.ReadInt(m_arNumbering[nIndex].m_nCharShape);
oBuffer.ReadString(m_arNumbering[nIndex].m_sNumFormat);
oBuffer.ReadString(m_arNumbering[nIndex].m_sNumFormat, EStringCharacter::UTF16);
}
oBuffer.ReadShort(m_shStart);

View File

@ -24,14 +24,14 @@ CHWPRecordParaText::CHWPRecordParaText(int nTagNum, int nLevel, int nSize)
LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
{
STRING sText;
oBuffer.ReadString(sText, nSize);
oBuffer.ReadString(sText, nSize, EStringCharacter::UTF16);
if (sText.empty())
return LIST<CCtrl*>();
std::regex oRegex("[\\u0000\\u000a\\u000d\\u0018-\\u001f]|[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017].{6}[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017]");
std::sregex_iterator itCurrent(sText.begin(), sText.end(), oRegex);
std::sregex_iterator itEnd;
std::wregex oRegex(L"[\\u0000\\u000a\\u000d\\u0018-\\u001f]|[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017].{6}[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017]");
std::wsregex_iterator itCurrent(sText.begin(), sText.end(), oRegex);
std::wsregex_iterator itEnd;
int nPrevIndex = 0;
@ -42,7 +42,7 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
if (itCurrent->position() > nPrevIndex)
{
// write text
arParas.push_back(new CParaText("____", sText.substr(nPrevIndex, itCurrent->position() - nPrevIndex), nPrevIndex));
arParas.push_back(new CParaText(L"____", sText.substr(nPrevIndex, itCurrent->position() - nPrevIndex), nPrevIndex));
}
if (1 == itCurrent->length())
@ -51,23 +51,23 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
{
case 0x0a:
{
arParas.push_back(new CCtrlCharacter(" _", ECtrlCharType::LINE_BREAK));
arParas.push_back(new CCtrlCharacter(L" _", ECtrlCharType::LINE_BREAK));
break;
}
case 0x0d:
{
arParas.push_back(new CCtrlCharacter(" _", ECtrlCharType::PARAGRAPH_BREAK));
arParas.push_back(new CCtrlCharacter(L" _", ECtrlCharType::PARAGRAPH_BREAK));
break;
}
case 0x18:
{
arParas.push_back(new CCtrlCharacter(" _", ECtrlCharType::HARD_HYPHEN));
arParas.push_back(new CCtrlCharacter(L" _", ECtrlCharType::HARD_HYPHEN));
break;
}
case 0x1e:
case 0x1f:
{
arParas.push_back(new CCtrlCharacter(" _", ECtrlCharType::HARD_SPACE));
arParas.push_back(new CCtrlCharacter(L" _", ECtrlCharType::HARD_SPACE));
break;
}
}
@ -83,7 +83,7 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
break;
case 0x09:
{
arParas.push_back(new CParaText("____", "\t", 0));
arParas.push_back(new CParaText(L"____", L"\t", 0));
break;
}
case 0x10:
@ -99,14 +99,14 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
case 0x15:
{
// if ("dhgp" == sInfo) break;
if ("pngp" == sInfo) arParas.push_back(new CCtrlPageNumPos(sInfo));
else if ("onwn" == sInfo) arParas.push_back(new CCtrlNewNumber(sInfo));
if (L"pngp" == sInfo) arParas.push_back(new CCtrlPageNumPos(sInfo));
else if (L"onwn" == sInfo) arParas.push_back(new CCtrlNewNumber(sInfo));
break;
}
case 0x02:
{
if ("dces" == sInfo) arParas.push_back(new CCtrlSectionDef(sInfo));
else if ("dloc" == sInfo) arParas.push_back(new CCtrlColumnDef(sInfo));
if (L"dces" == sInfo) arParas.push_back(new CCtrlSectionDef(sInfo));
else if (L"dloc" == sInfo) arParas.push_back(new CCtrlColumnDef(sInfo));
break;
}
case 0x03:
@ -123,11 +123,11 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
break;
case 0x0b:
{
if (" osg" == sInfo)
if (L" osg" == sInfo)
arParas.push_back(new CCtrlGeneralShape(sInfo));
else if (" lbt" == sInfo)
else if (L" lbt" == sInfo)
arParas.push_back(new CCtrlTable(sInfo));
else if ("deqe" == sInfo)
else if (L"deqe" == sInfo)
arParas.push_back(new CCtrlEqEdit(sInfo));
// else if ("mrof" == sInfo)
break;
@ -142,7 +142,7 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
if (nPrevIndex < sText.length())
{
// write final text
arParas.push_back(new CParaText("____", sText.substr(nPrevIndex), nPrevIndex));
arParas.push_back(new CParaText(L"____", sText.substr(nPrevIndex), nPrevIndex));
}
}

View File

@ -9,8 +9,8 @@ CHWPRecordStyle::CHWPRecordStyle(int nTagNum, int nLevel, int nSize)
CHWPRecordStyle::CHWPRecordStyle(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
: CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo)
{
oBuffer.ReadString(m_sName);
oBuffer.ReadString(m_sEngName);
oBuffer.ReadString(m_sName, EStringCharacter::UTF16);
oBuffer.ReadString(m_sEngName, EStringCharacter::UTF16);
m_chType = (BYTE)(oBuffer.ReadByte() & 0x00FF);
m_chNextStyle = (BYTE)(oBuffer.ReadByte() & 0x00FF);

View File

@ -1,4 +1,4 @@
#include "HWPFile.h"
#include "HWPFile_Private.h"
#include "HWPDocInfo.h"
#include "../DesktopEditor/common/Directory.h"
@ -6,17 +6,17 @@
namespace HWP
{
CHWPFile::CHWPFile(const STRING& sFileName)
CHWPFile_Private::CHWPFile_Private(const STRING& sFileName)
: m_sFileName(sFileName), m_oOleFile(sFileName), m_oDocInfo(this)
{}
CHWPFile::~CHWPFile()
CHWPFile_Private::~CHWPFile_Private()
{
CLEAR_ARRAY(CHWPSection, m_arBodyTexts);
CLEAR_ARRAY(CHWPSection, m_arViewTexts);
}
std::vector<CHWPSection*> CHWPFile::GetSections()
std::vector<CHWPSection*> CHWPFile_Private::GetSections()
{
if (m_oFileHeader.Distributable())
return m_arViewTexts;
@ -24,12 +24,12 @@ std::vector<CHWPSection*> CHWPFile::GetSections()
return m_arBodyTexts;
}
const CCompoundFile* CHWPFile::GetOleFile() const
const CCompoundFile* CHWPFile_Private::GetOleFile() const
{
return &m_oOleFile;
}
bool CHWPFile::Detect()
bool CHWPFile_Private::Detect()
{
// read CompoundFile structure
if (!m_oOleFile.Open() || !GetFileHeader())
@ -41,10 +41,10 @@ bool CHWPFile::Detect()
return true;
}
bool CHWPFile::Open()
bool CHWPFile_Private::Open()
{
if (m_oFileHeader.SignatureEmpty() || m_oFileHeader.VersionEmpty())
Detect();
if ((m_oFileHeader.SignatureEmpty() || m_oFileHeader.VersionEmpty()) && !Detect())
return false;
//TODO:: добавить отдельный метод StringToInt
m_nVersion = std::stoi(m_oFileHeader.GetVersion());
@ -65,12 +65,12 @@ bool CHWPFile::Open()
return true;
}
void CHWPFile::Close()
void CHWPFile_Private::Close()
{
m_oOleFile.Close();
}
void CHWPFile::SaveHWPComponent()
void CHWPFile_Private::SaveHWPComponent()
{
ECompressed eCompressed = m_oFileHeader.Compressed() ? ECompressed::COMPRESS : ECompressed::NO_COMPRESS;
@ -78,80 +78,80 @@ void CHWPFile::SaveHWPComponent()
// TODO:: перенести
}
bool CHWPFile::GetFileHeader()
bool CHWPFile_Private::GetFileHeader()
{
CHWPStream oBuffer;
if (!GetComponent("FileHeader", oBuffer))
if (!GetComponent(L"FileHeader", oBuffer))
return false;
return m_oFileHeader.Parse(oBuffer);
}
const CHWPDocInfo* CHWPFile::GetDocInfo() const
const CHWPDocInfo* CHWPFile_Private::GetDocInfo() const
{
return &m_oDocInfo;
}
bool CHWPFile::GetDocInfo(int nVersion)
bool CHWPFile_Private::GetDocInfo(int nVersion)
{
CHWPStream oBuffer;
if (m_oFileHeader.Compressed())
{
CHWPStream oTempBuffer;
if (!GetComponent("DocInfo", oTempBuffer) && !Unzip(oTempBuffer, oBuffer))
if (!GetComponent(L"DocInfo", oTempBuffer) && !Unzip(oTempBuffer, oBuffer))
return false;
}
else
{
if (GetComponent("DocInfo", oBuffer))
if (GetComponent(L"DocInfo", oBuffer))
return false;
}
return m_oDocInfo.Parse(oBuffer, m_nVersion);
}
bool CHWPFile::GetComponent(const std::string& sEntryName, CHWPStream& oBuffer)
bool CHWPFile_Private::GetComponent(const STRING& sEntryName, CHWPStream& oBuffer)
{
return m_oOleFile.GetComponent(sEntryName, oBuffer);
}
//TODO:: написанно, что данные методы используются только для отображения в LibbreOffice
// проверить и если нужны будут, то реализовать
VECTOR<CDirectoryEntry*> CHWPFile::GetBinData()
VECTOR<CDirectoryEntry*> CHWPFile_Private::GetBinData()
{
return VECTOR<CDirectoryEntry*>();
}
void CHWPFile::SetBinData(const std::vector<CDirectoryEntry*>& arBinData)
void CHWPFile_Private::SetBinData(const std::vector<CDirectoryEntry*>& arBinData)
{
}
VECTOR<CHWPPargraph*> CHWPFile::GetParas()
VECTOR<CHWPPargraph*> CHWPFile_Private::GetParas()
{
return VECTOR<CHWPPargraph*>();
}
void CHWPFile::AddParas(const std::vector<CHWPPargraph*>& arParas)
void CHWPFile_Private::AddParas(const std::vector<CHWPPargraph*>& arParas)
{
}
//------------
void CHWPFile::SaveChildEntries(const std::string& sBasePath, const std::string& sStorageName, ECompressed eCompressed)
void CHWPFile_Private::SaveChildEntries(const STRING& sBasePath, const STRING& sStorageName, ECompressed eCompressed)
{
// TODO:: перенести
}
CDirectoryEntry* CHWPFile::FindChildEntry(const std::string& sBasePath, const CDirectoryEntry& oBaseEntry, const std::string& sEntryName)
CDirectoryEntry* CHWPFile_Private::FindChildEntry(const STRING& sBasePath, const CDirectoryEntry& oBaseEntry, const STRING& sEntryName)
{
for (CDirectoryEntry* pEntry : m_oOleFile.GetChildEntries(&oBaseEntry))
{
if (0x01 == pEntry->GetObjectType())
{
//TODO:: проверить
STRING sChildPath = sBasePath + FILE_SEPARATOR_CHAR + pEntry->GetDirectoryEntryName();
STRING sChildPath = sBasePath + FILE_SEPARATOR_STR + pEntry->GetDirectoryEntryName();
return FindChildEntry(sChildPath, *pEntry, sEntryName);
}
else
@ -164,28 +164,28 @@ CDirectoryEntry* CHWPFile::FindChildEntry(const std::string& sBasePath, const CD
return nullptr;
}
STRING CHWPFile::SaveChildEntry(const std::string& sRootPath, const std::string& sEntryName, ECompressed eCompressed)
STRING CHWPFile_Private::SaveChildEntry(const STRING& sRootPath, const STRING& sEntryName, ECompressed eCompressed)
{
//TODO:: перенести
return STRING();
}
bool CHWPFile::GetChildStream(const std::string& sEntryName, ECompressed eCompressed, CHWPStream& oBuffer)
bool CHWPFile_Private::GetChildStream(const STRING& sEntryName, ECompressed eCompressed, CHWPStream& oBuffer)
{
STRING sRegexStr = ".*" + STRING(FILE_SEPARATOR_STRA) + "([" + STRING(FILE_SEPARATOR_STRA) + "]+)$";
STRING sRegexStr = L".*" + STRING(FILE_SEPARATOR_STR) + L"([" + STRING(FILE_SEPARATOR_STR) + L"]+)$";
STRING sShortFilename = std::regex_replace(m_sFileName, std::regex(sRegexStr), "$1");
sShortFilename = std::regex_replace(sShortFilename, std::regex("(.*)\\.hwp$"), "$1");
STRING sShortFilename = std::regex_replace(m_sFileName, std::wregex(sRegexStr), L"$1");
sShortFilename = std::regex_replace(sShortFilename, std::wregex(L"(.*)\\.hwp$"), L"$1");
CDirectoryEntry *pTargetEntry = nullptr;
VECTOR<CDirectoryEntry*> arEntries = m_oOleFile.GetChildEntries("Root Entry");
VECTOR<CDirectoryEntry*> arEntries = m_oOleFile.GetChildEntries(L"Root Entry");
for (CDirectoryEntry* pEntry : arEntries)
{
if (0x01 == pEntry->GetObjectType())
{
STRING sChildPath = sShortFilename + FILE_SEPARATOR_CHAR + pEntry->GetDirectoryEntryName();
STRING sChildPath = sShortFilename + FILE_SEPARATOR_STR + pEntry->GetDirectoryEntryName();
pTargetEntry = FindChildEntry(sChildPath, *pEntry, sEntryName);
if (nullptr != pTargetEntry)
@ -218,13 +218,13 @@ bool CHWPFile::GetChildStream(const std::string& sEntryName, ECompressed eCompre
return false;
}
bool CHWPFile::Unzip(CHWPStream& oInput, CHWPStream& oBuffer)
bool CHWPFile_Private::Unzip(CHWPStream& oInput, CHWPStream& oBuffer)
{
//TODO:: реализовать
return false;
}
bool CHWPFile::Decrypt(CHWPStream& oInput, CHWPStream& oBuffer)
bool CHWPFile_Private::Decrypt(CHWPStream& oInput, CHWPStream& oBuffer)
{
int nHeader;
oInput.ReadInt(nHeader);
@ -245,9 +245,9 @@ bool CHWPFile::Decrypt(CHWPStream& oInput, CHWPStream& oBuffer)
return false;
}
bool CHWPFile::GetBodyText(int nVersion)
bool CHWPFile_Private::GetBodyText(int nVersion)
{
VECTOR<CDirectoryEntry*> arSections{m_oOleFile.GetChildEntries("BodyText")};
VECTOR<CDirectoryEntry*> arSections{m_oOleFile.GetChildEntries(L"BodyText")};
for (const CDirectoryEntry* pSection : arSections)
{
@ -270,9 +270,9 @@ bool CHWPFile::GetBodyText(int nVersion)
return true;
}
bool CHWPFile::GetViewText(int nVersion)
bool CHWPFile_Private::GetViewText(int nVersion)
{
VECTOR<CDirectoryEntry*> arSections{m_oOleFile.GetChildEntries("ViewText")};
VECTOR<CDirectoryEntry*> arSections{m_oOleFile.GetChildEntries(L"ViewText")};
for (const CDirectoryEntry* pSection : arSections)
{

View File

@ -1,5 +1,5 @@
#ifndef HWPFILE_H
#define HWPFILE_H
#ifndef HWPFILE_PRIVATE_H
#define HWPFILE_PRIVATE_H
#include "HwpFileHeader.h"
#include "OLEdoc/CompoundFile.h"
@ -8,8 +8,7 @@
namespace HWP
{
class CHWPDocInfo;
class CHWPFile
class CHWPFile_Private
{
STRING m_sFileName;
CCompoundFile m_oOleFile;
@ -19,8 +18,8 @@ class CHWPFile
VECTOR<CHWPSection*> m_arBodyTexts;
VECTOR<CHWPSection*> m_arViewTexts;
public:
CHWPFile(const STRING& sFileName);
~CHWPFile();
CHWPFile_Private(const STRING& sFileName);
~CHWPFile_Private();
VECTOR<CHWPSection*> GetSections();
const CCompoundFile* GetOleFile() const;
@ -53,4 +52,4 @@ private:
};
}
#endif // HWPFILE_H
#endif // HWPFILE_PRIVATE_H

View File

@ -79,6 +79,14 @@ bool CHWPSection::Parse(CHWPStream& oBuffer, int nVersion)
return true;
}
#define FIND_LAST_ELEMENT(type, ptr, container_type, container) \
for (VECTOR<container_type*>::const_reverse_iterator itCtrl = container.crbegin(); itCtrl != container.crend(); ++itCtrl) \
{ \
if (nullptr != dynamic_cast<type*>(*itCtrl)) \
ptr = (type*)(*itCtrl); \
}
int CHWPSection::ParseRecurse(CHWPPargraph& oCurrPara, int nRunLevel, CHWPStream& oBuffer, int nOff, int nVersion)
{
oBuffer.SavePosition();
@ -126,7 +134,11 @@ int CHWPSection::ParseRecurse(CHWPPargraph& oCurrPara, int nRunLevel, CHWPStream
}
case HWPTAG_TABLE:
{
CCtrlTable *pTable = oCurrPara.FindLastElement<CCtrlTable>();
CCtrlTable *pTable = nullptr;
const VECTOR<CCtrl*> arCtrls = oCurrPara.GetCtrls();
FIND_LAST_ELEMENT(CCtrlTable, pTable, CCtrl, arCtrls);
if (nullptr != pTable)
ParseCtrlRecurse(*pTable, nLevel, oBuffer, 0, nVersion);
@ -143,7 +155,7 @@ int CHWPSection::ParseRecurse(CHWPPargraph& oCurrPara, int nRunLevel, CHWPStream
case HWPTAG_FOOTNOTE_SHAPE:
case HWPTAG_PAGE_BORDER_FILL:
{
CCtrlSectionDef *pCtrlSecDef = dynamic_cast<CCtrlSectionDef*>(oCurrPara.FindLastElement("dces"));
CCtrlSectionDef *pCtrlSecDef = dynamic_cast<CCtrlSectionDef*>(oCurrPara.FindLastElement(L"dces"));
if (nullptr != pCtrlSecDef)
ParseCtrlRecurse(*pCtrlSecDef, nLevel, oBuffer, 0, nVersion);
@ -163,7 +175,7 @@ int CHWPSection::ParseRecurse(CHWPPargraph& oCurrPara, int nRunLevel, CHWPStream
case HWPTAG_SHAPE_COMPONENT_TEXTART:
case HWPTAG_SHAPE_COMPONENT_UNKNOWN:
{
CCtrlGeneralShape *pCtrlGeneral = dynamic_cast<CCtrlGeneralShape*>(oCurrPara.FindLastElement(" osg"));
CCtrlGeneralShape *pCtrlGeneral = dynamic_cast<CCtrlGeneralShape*>(oCurrPara.FindLastElement(L" osg"));
if (nullptr != pCtrlGeneral)
ParseCtrlRecurse(*pCtrlGeneral, nLevel, oBuffer, 0, nVersion);
@ -178,7 +190,11 @@ int CHWPSection::ParseRecurse(CHWPPargraph& oCurrPara, int nRunLevel, CHWPStream
case HWPTAG_VIDEO_DATA:
default:
{
CCtrlCommon *pCtrlCommon = oCurrPara.FindLastElement<CCtrlCommon>();
CCtrlCommon *pCtrlCommon = nullptr;
const VECTOR<CCtrl*> arCtrls = oCurrPara.GetCtrls();
FIND_LAST_ELEMENT(CCtrlCommon, pCtrlCommon, CCtrl, arCtrls);
if (nullptr != pCtrlCommon)
ParseCtrlRecurse(*pCtrlCommon, nLevel, oBuffer, 0, nVersion);
@ -225,7 +241,7 @@ int CHWPSection::ParseRecurse(CHWPPargraph& oCurrPara, int nRunLevel, CHWPStream
case HWPTAG_PARA_CHAR_SHAPE:
{
if (0 == oCurrPara.GetCountCtrls())
oCurrPara.AddCtrl(new CCtrlCharacter(" _", ECtrlCharType::PARAGRAPH_BREAK));
oCurrPara.AddCtrl(new CCtrlCharacter(L" _", ECtrlCharType::PARAGRAPH_BREAK));
CCharShape::FillCharShape(nTagNum, nLevel, nSize, oBuffer, 0, nVersion, oCurrPara.GetCtrls());
}
@ -254,7 +270,7 @@ int CHWPSection::ParseRecurse(CHWPPargraph& oCurrPara, int nRunLevel, CHWPStream
if (nullptr != dynamic_cast<CCtrlHeadFoot*>(pCtrl))
{
CCtrlSectionDef* pSecD = dynamic_cast<CCtrlSectionDef*>(oCurrPara.FindLastElement("dces"));
CCtrlSectionDef* pSecD = dynamic_cast<CCtrlSectionDef*>(oCurrPara.FindLastElement(L"dces"));
if (nullptr != pSecD)
pSecD->AddHeadFoot((CCtrlHeadFoot*)pCtrl);
@ -361,56 +377,67 @@ int CHWPSection::ParseContainerRecurse(CCtrlContainer& oContainer, int nRunLevel
{
oBuffer.Skip(nHeaderSize);
#define CHECK_SHAPE(shapeType) \
const VECTOR<CCtrlGeneralShape*> arCtrls = oContainer.GetShapes(); \
shapeType *pCtrl = nullptr; \
FIND_LAST_ELEMENT(shapeType, pCtrl, CCtrlGeneralShape, arCtrls); \
if (nullptr == pCtrl) \
{ \
pCtrl = new shapeType(); \
oContainer.AddShape(pCtrl); \
} \
shapeType::ParseElement((shapeType&)(*pCtrl), nSize, oBuffer, 0, nVersion)
switch (eTag)
{
case HWPTAG_SHAPE_COMPONENT_PICTURE:
{
CheckShape<CCtrlShapePic>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlShapePic);
break;
}
case HWPTAG_SHAPE_COMPONENT_LINE:
{
CheckShape<CCtrlShapeLine>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlShapeLine);
break;
}
case HWPTAG_SHAPE_COMPONENT_RECTANGLE:
{
CheckShape<CCtrlShapeRect>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlShapeRect);
break;
}
case HWPTAG_SHAPE_COMPONENT_ELLIPSE:
{
CheckShape<CCtrlShapeEllipse>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlShapeEllipse);
break;
}
case HWPTAG_SHAPE_COMPONENT_ARC:
{
CheckShape<CCtrlShapeArc>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlShapeArc);
break;
}
case HWPTAG_SHAPE_COMPONENT_POLYGON:
{
CheckShape<CCtrlShapePolygon>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlShapePolygon);
break;
}
case HWPTAG_SHAPE_COMPONENT_CURVE:
{
CheckShape<CCtrlShapeCurve>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlShapeCurve);
break;
}
case HWPTAG_SHAPE_COMPONENT_OLE:
{
CheckShape<CCtrlShapeOle>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlShapeOle);
break;
}
case HWPTAG_EQEDIT:
{
CheckShape<CCtrlEqEdit>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlEqEdit);
break;
}
case HWPTAG_SHAPE_COMPONENT_TEXTART:
{
CheckShape<CCtrlShapeTextArt>(oContainer, nSize, oBuffer, nVersion);
CHECK_SHAPE(CCtrlShapeTextArt);
break;
}
case HWPTAG_LIST_HEADER:
@ -429,9 +456,9 @@ int CHWPSection::ParseContainerRecurse(CCtrlContainer& oContainer, int nRunLevel
if (bIsShapeRect || bIsShapePolygon)
{
if (bIsShapeRect)
pCtrl->SetID("cer$");
pCtrl->SetID(L"cer$");
else
pCtrl->SetID("lop$");
pCtrl->SetID(L"lop$");
oBuffer.Skip(-6);
pCtrl->SetTextVerAlign(CHWPRecordListHeader::GetVertAlign(6, oBuffer, 0, nVersion));
@ -543,17 +570,17 @@ int CHWPSection::ParseListAppend(CCtrlCommon& oObj, int nSize, CHWPStream& oBuff
{
oBuffer.SavePosition();
if ("cer$" == oObj.GetID())
if (L"cer$" == oObj.GetID())
CCtrlShapeRect::ParseListHeaderAppend((CCtrlShapeRect&)(oObj), nSize, oBuffer, 0, nVersion);
else if (" osg" == oObj.GetID())
else if (L" osg" == oObj.GetID())
CCtrlGeneralShape::ParseListHeaderApend((CCtrlGeneralShape&)(oObj), nSize, oBuffer, 0, nVersion);
else if (" lbt" == oObj.GetID())
else if (L" lbt" == oObj.GetID())
CCtrlTable::ParseListHeaderAppend((CCtrlTable&)(oObj), nSize, oBuffer, 0, nVersion);
else if ("deqe" == oObj.GetID())
else if (L"deqe" == oObj.GetID())
CCtrlEqEdit::ParseListHeaderAppend((CCtrlEqEdit&)(oObj), nSize, oBuffer, 0, nVersion);
else if ("lop$" == oObj.GetID())
else if (L"lop$" == oObj.GetID())
CCtrlShapePolygon::ParseListHeaderAppend((CCtrlShapePolygon&)(oObj), nSize, oBuffer, 0, nVersion);
else if ("lle$" == oObj.GetID())
else if (L"lle$" == oObj.GetID())
CCtrlShapeEllipse::ParseListHeaderAppend((CCtrlShapeEllipse&)(oObj), nSize, oBuffer, 0, nVersion);
return oBuffer.GetDistanceToLastPos();
@ -561,26 +588,13 @@ int CHWPSection::ParseListAppend(CCtrlCommon& oObj, int nSize, CHWPStream& oBuff
int CHWPSection::ParseListAppend(CCtrl& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
{
if ("dces" == oObj.GetID())
if (L"dces" == oObj.GetID())
oBuffer.Skip(nSize - 6);
else if ("daeh" == oObj.GetID() || "toof" == oObj.GetID())
else if (L"daeh" == oObj.GetID() || L"toof" == oObj.GetID())
CCtrlHeadFoot::ParseListHeaderAppend((CCtrlHeadFoot&)(oObj), nSize, oBuffer, 0, nVersion);
// else if (" nf" == oObj.GetID())
return nSize;
}
template<typename ShapeType>
void CHWPSection::CheckShape(CCtrlContainer& oContainer, int nSize, CHWPStream& oBuffer, int nVersion)
{
ShapeType *pCtrl = oContainer.FindLastElement<ShapeType>();
if (nullptr == pCtrl)
{
pCtrl = new ShapeType();
oContainer.AddShape(pCtrl);
}
ShapeType::ParseElement((ShapeType&)(*pCtrl), nSize, oBuffer, 0, nVersion);
}
}

View File

@ -12,9 +12,6 @@ class CHWPSection
int ParseListAppend(CCtrlCommon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
int ParseListAppend(CCtrl& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
template <typename ShapeType>
void CheckShape(CCtrlContainer& oContainer, int nSize, CHWPStream& oBuffer, int nVersion);
public:
CHWPSection();
~CHWPSection();

View File

@ -1,5 +1,7 @@
#include "HWPStream.h"
#include "../../DesktopEditor/common/StringExt.h"
namespace HWP
{
CHWPStream::CHWPStream()
@ -47,35 +49,55 @@ unsigned int CHWPStream::Tell() const
bool CHWPStream::ReadChar(CHAR& chValue)
{
//TODO:: реализовать
Skip(2);
if (m_pCur + 2 > m_pEnd)
return false;
chValue = (CHAR)(((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[0] & 0x000000FF));
m_pCur += 2;
return true;
}
bool CHWPStream::ReadFloat(float& fValue)
{
//TODO:: реализовать
Skip(4);
//TODO:: Проверить
int nValue;
if (!ReadInt(nValue))
return false;
fValue = *(float*)&nValue;
return true;
}
bool CHWPStream::ReadDouble(double& dValue)
{
//TODO:: реализовать
Skip(8);
long long lValue;
if (!ReadLong(lValue))
return false;
dValue = *(double*)&lValue;
return true;
}
bool CHWPStream::ReadLong(long& lValue)
bool CHWPStream::ReadLong(long long& lValue)
{
//TODO:: реализовать
Skip(8);
if (m_pCur + 8 > m_pEnd)
return false;
lValue = ((m_pCur[7] << 24) & 0xFF000000) | ((m_pCur[6 ]<< 16) & 0xFF0000) | ((m_pCur[5] << 8) & 0xFF00) | (m_pCur[4] & 0xFF);
lValue = (lValue << 32) | ((m_pCur[3] << 24) & 0xFF000000) | ((m_pCur[2] << 16) & 0xFF0000) | ((m_pCur[1] << 8) & 0xFF00) | (m_pCur[0] & 0xFF);
m_pCur += 8;
return true;
}
bool CHWPStream::ReadInt(int& nValue)
{
if (m_pCur + 4 >= m_pEnd)
if (m_pCur + 4 > m_pEnd)
return false;
nValue = ((m_pCur[3] << 24) & 0xFF000000) | ((m_pCur[2] << 16) & 0x00FF0000) | ((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[0] & 0x000000FF);
@ -86,7 +108,7 @@ bool CHWPStream::ReadInt(int& nValue)
bool CHWPStream::ReadColor(int& nValue)
{
if (m_pCur + 4 >= m_pEnd)
if (m_pCur + 4 > m_pEnd)
return false;
nValue = ((m_pCur[3] << 24) & 0xFF000000) | ((m_pCur[0] << 16) & 0x00FF0000) | ((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[2] & 0x000000FF);
@ -97,7 +119,7 @@ bool CHWPStream::ReadColor(int& nValue)
bool CHWPStream::ReadShort(short& shValue)
{
if (m_pCur + 2 >= m_pEnd)
if (m_pCur + 2 > m_pEnd)
return false;
shValue = (short)(((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[0] & 0x000000FF));
@ -108,7 +130,7 @@ bool CHWPStream::ReadShort(short& shValue)
short CHWPStream::ReadShort()
{
if (m_pCur + 2 >= m_pEnd)
if (m_pCur + 1 > m_pEnd)
return 0;
short shValue = (short)(((m_pCur[1] << 8) & 0x0000FF00) | (m_pCur[0] & 0x000000FF));
@ -119,7 +141,7 @@ short CHWPStream::ReadShort()
bool CHWPStream::ReadByte(BYTE& chValue)
{
if (m_pCur + 1 >= m_pEnd)
if (m_pCur + 1 > m_pEnd)
return false;
chValue = m_pCur[0];
@ -130,7 +152,7 @@ bool CHWPStream::ReadByte(BYTE& chValue)
BYTE CHWPStream::ReadByte()
{
if (m_pCur + 1 >= m_pEnd)
if (m_pCur + 1 > m_pEnd)
return 0;
BYTE chValue = m_pCur[0]++;
@ -139,30 +161,29 @@ BYTE CHWPStream::ReadByte()
return chValue;
}
bool CHWPStream::ReadString(STRING& sValue)
void Trim(STRING& sValue)
{
sValue.clear();
STRING::const_iterator itBegin = std::find_if(sValue.cbegin(), sValue.cend(), [](wchar_t wChar){ return !iswcntrl(wChar); });
if (itBegin != sValue.cend())
sValue.erase(0, itBegin - sValue.cbegin());
STRING::const_reverse_iterator itEnd = std::find_if(sValue.crbegin(), sValue.crend(), [](wchar_t wChar){ return !iswcntrl(wChar); });
if (itEnd != sValue.crend())
sValue.erase(itEnd.base());
}
bool CHWPStream::ReadString(STRING& sValue, EStringCharacter eCharacter)
{
short shLen;
if (!ReadShort(shLen))
return false;
if (0 == shLen)
return true;
int nLen = (int)shLen * 2;
if (!CanRead(nLen))
nLen = m_pEnd - GetCurPtr();
sValue = STRING(GetCurPtr(), nLen); //TODO:: StandardCharsets.UTF_16LE
Skip(nLen);
return true;
return ReadString(sValue, (int)shLen * 2, eCharacter);
}
bool CHWPStream::ReadString(STRING& sValue, int nLength)
bool CHWPStream::ReadString(STRING& sValue, int nLength, EStringCharacter eCharacter)
{
sValue.clear();
@ -172,8 +193,26 @@ bool CHWPStream::ReadString(STRING& sValue, int nLength)
if (!CanRead(nLength))
nLength = m_pEnd - GetCurPtr();
sValue = STRING(GetCurPtr(), nLength); //TODO:: StandardCharsets.UTF_16LE
switch (eCharacter)
{
case EStringCharacter::ASCII:
{
sValue = NSStringExt::CConverter::GetUnicodeFromSingleByteString((unsigned char*)GetCurPtr(), nLength);
break;
}
case EStringCharacter::UTF16:
{
sValue = NSStringExt::CConverter::GetUnicodeFromUTF16((unsigned short*)GetCurPtr(), nLength / 2);
break;
}
case EStringCharacter::UTF32:
{
sValue = NSStringExt::CConverter::GetUnicodeFromUTF32((unsigned int*)GetCurPtr(), nLength / 4);
break;
}
}
Trim(sValue);
Skip(nLength);
return true;
@ -185,12 +224,13 @@ bool CHWPStream::ReadBytes(char* pBytes, unsigned int unSize)
return false;
memcpy(pBytes, m_pCur, unSize);
m_pCur += unSize;
return true;
}
void CHWPStream::Skip(unsigned int unStep)
{
if (m_pCur + unStep >= m_pEnd)
if (m_pCur + unStep > m_pEnd)
m_pCur = m_pEnd;
else
m_pCur += unStep;
@ -227,10 +267,10 @@ bool CHWPStream::IsValid() const
bool CHWPStream::IsEof() const
{
return m_pCur >= m_pEnd;
return m_pCur > m_pEnd;
}
unsigned int CHWPStream::GetLength() const
unsigned int CHWPStream::GetSize() const
{
return (unsigned int)(m_pEnd - m_pCur);
}
@ -258,8 +298,8 @@ int CHWPStream::GetDistanceToLastPos(bool bRemoveLastPos)
BYTE CHWPStream::operator[](unsigned int unPosition) const
{
if (m_pCur >= m_pEnd)
return *m_pEnd;
if (m_pCur > m_pEnd)
return *(m_pEnd - 1);
return *(m_pCur + unPosition);
}

View File

@ -7,6 +7,13 @@
namespace HWP
{
enum class EStringCharacter
{
ASCII,
UTF16,
UTF32
};
class CHWPStream
{
BYTE* m_pBegin;
@ -29,15 +36,15 @@ public:
bool ReadChar(CHAR& chValue);
bool ReadFloat(float& fValue);
bool ReadDouble(double& dValue);
bool ReadLong(long& lValue);
bool ReadLong(long long& lValue);
bool ReadInt(int& nValue);
bool ReadColor(int& nValue);
bool ReadShort(short& shValue);
short ReadShort();
bool ReadByte(BYTE& chValue);
BYTE ReadByte();
bool ReadString(STRING& sValue);
bool ReadString(STRING& sValue, int nLength);
bool ReadString(STRING& sValue, EStringCharacter eCharacter);
bool ReadString(STRING& sValue, int nLength, EStringCharacter eCharacter);
bool ReadBytes(BYTE* pBytes, unsigned int unSize);
void Skip(unsigned int unStep);
@ -47,7 +54,7 @@ public:
bool CanRead(int nSize = 1) const;
bool IsValid() const;
bool IsEof() const;
unsigned int GetLength() const;
unsigned int GetSize() const;
void SavePosition();
void RemoveLastSavedPos();

View File

@ -7,16 +7,18 @@ CHwpFileHeader::CHwpFileHeader()
bool CHwpFileHeader::Parse(CHWPStream& oBuffer)
{
unsigned int unOffset = 0;
m_sSignature = STRING((char*)oBuffer.GetCurPtr(), 32);
if ("HWP Document File" != m_sSignature)
if (!oBuffer.IsValid())
return false;
unOffset += 32;
unsigned int unOffset = 0;
oBuffer.ReadString(m_sSignature, 32, EStringCharacter::ASCII);
if (L"HWP Document File" != m_sSignature)
return false;
//version
m_sVersion = std::to_wstring((int)oBuffer[unOffset + 3]) + std::to_wstring((int)oBuffer[unOffset + 2]) + std::to_wstring((int)oBuffer[unOffset + 1]) + std::to_wstring((int)oBuffer[unOffset + 0]);
unOffset += 4;
m_bCompressed = CHECK_FLAG(oBuffer[unOffset], 0x01);

View File

@ -1,21 +1,19 @@
#include "CompoundFile.h"
#include <cwctype>
namespace HWP
{
CCompoundFile::CCompoundFile(const std::string& sFileName)
: m_fFile(sFileName), m_nSectorSize(512)
CCompoundFile::CCompoundFile(const STRING& sFileName)
: m_fFile(sFileName, std::ios::in | std::ios::binary), m_nSectorSize(512)
{}
CCompoundFile::~CCompoundFile()
{
if (m_fFile.is_open())
m_fFile.close();
Close();
CLEAR_ARRAY(CDirectoryEntry, m_arDirectoryEntries);
}
const CDirectoryEntry* CCompoundFile::GetEntry(const std::string& sFileName) const
const CDirectoryEntry* CCompoundFile::GetEntry(const STRING& sFileName) const
{
VECTOR<CDirectoryEntry*>::const_iterator itFound = std::find_if(m_arDirectoryEntries.cbegin(), m_arDirectoryEntries.cend(), [&sFileName](const CDirectoryEntry* pDirectoryEntry){ return sFileName == pDirectoryEntry->GetDirectoryEntryName();});
@ -25,7 +23,7 @@ const CDirectoryEntry* CCompoundFile::GetEntry(const std::string& sFileName) con
return *itFound;
}
bool CCompoundFile::GetComponent(const std::string& sEntryName, CHWPStream& oBuffer)
bool CCompoundFile::GetComponent(const STRING& sEntryName, CHWPStream& oBuffer)
{
const CDirectoryEntry* pEntry = GetEntry(sEntryName);
@ -42,7 +40,12 @@ VECTOR<CDirectoryEntry*> CCompoundFile::GetChildEntries(const CDirectoryEntry* p
int nIndex = 0;
if (nullptr == pBaseEntry)
nIndex = m_arDirectoryEntries.at(0)->GetChildID();
{
if (!m_arDirectoryEntries.empty())
nIndex = m_arDirectoryEntries.at(0)->GetChildID();
else
return VECTOR<CDirectoryEntry*>();
}
else
nIndex = pBaseEntry->GetChildID();
@ -86,17 +89,24 @@ bool CCompoundFile::Read(const CDirectoryEntry& oEntry, CHWPStream& oBuffer)
if (oEntry.GetStreamSize() < m_nMiniStreamCutoffSize)
{
if ( m_arDirectoryEntries.empty())
return false;
arStreamContainerSectors = m_arDirectoryEntries.at(0)->GetSecNums();
for (int nSecNum : oEntry.GetSecNums())
{
int nStreamIndex = nSecNum / (m_nSectorSize / 64);
int nStreamOffset = nSecNum % (m_nSectorSize / 64);
if (nStreamIndex >= arStreamContainerSectors.size())
return false;
int nSatID = arStreamContainerSectors.at(nStreamIndex);
m_fFile.seekg((nSatID + 1) * m_nSectorSize + nStreamOffset * 64);
m_fFile.read(oBuffer.GetCurPtr(), nRemainSize >= 64 ? 64 : nRemainSize);
oBuffer.Skip(m_fFile.gcount());
nRemainSize -= m_fFile.gcount();
}
@ -111,6 +121,7 @@ bool CCompoundFile::Read(const CDirectoryEntry& oEntry, CHWPStream& oBuffer)
// readStream
m_fFile.seekg((nSecNum + 1) * m_nSectorSize);
m_fFile.read(oBuffer.GetCurPtr(), nRemainSize >= m_nSectorSize ? m_nSectorSize : nRemainSize);
oBuffer.Skip(m_fFile.gcount());
nRemainSize -= m_fFile.gcount();
}
@ -123,6 +134,9 @@ bool CCompoundFile::Read(const CDirectoryEntry& oEntry, CHWPStream& oBuffer)
bool CCompoundFile::Open()
{
if (m_fFile.bad())
return false;
CHWPStream oBuffer(m_nSectorSize);
if (!oBuffer.IsValid())
@ -154,6 +168,9 @@ bool CCompoundFile::Open()
int nSatIndex = nSecID / (m_nSectorSize / 4);
// collect Directory SecID
if (nSatIndex >= m_arSATs.size())
return false;
int nSatID = m_arSATs.at(nSatIndex);
VECTOR<int> arSecIDs = GetSecIDsFromSAT(nSatID, nSatIndex, nSecID);
@ -183,6 +200,10 @@ bool CCompoundFile::Open()
while (0xFFFFFFFE != nLastSecID)
{
int nSatIndex = nLastSecID / (m_nSectorSize / 4);
if (nSatIndex >= m_arSATs.size())
return false;
int nSatID = m_arSATs.at(nSatIndex);
VECTOR<int> arSecIDs = GetSecIDsFromSAT(nSatID, nSatIndex, nLastSecID);
@ -211,6 +232,10 @@ bool CCompoundFile::Open()
while (0xFFFFFFFE != nLastSecID)
{
int nContainerIndex = nLastSecID / (m_nSectorSize / 4);
if (nContainerIndex >= m_arSATs.size())
return false;
int nSatID = m_arSATs.at(nContainerIndex);
VECTOR<int> arSecIDs = GetSecIDsFromSAT(nSatID, nContainerIndex, nLastSecID);
@ -239,6 +264,10 @@ bool CCompoundFile::Open()
while (0xFFFFFFFE != nLastSSecID)
{
int nSSatIndex = nLastSSecID / (m_nSectorSize / 4);
if (nSSatIndex >= m_arSSATSecIDs.size())
return false;
int nSSatID = m_arSSATSecIDs.at(nSSatIndex);
VECTOR<int> arSecIDs = GetSecIDsFromSAT(nSSatID, nSSatIndex, nLastSSecID);
@ -263,6 +292,10 @@ bool CCompoundFile::Open()
while (0xFFFFFFFE != nLastSectID)
{
int nSatIndex = nLastSectID / (m_nSectorSize / 4);
if (nSatIndex >= m_arSATs.size())
return false;
int nSatID = m_arSATs.at(nSatIndex);
VECTOR<int> arSecIDs = GetSecIDsFromSAT(nSatID, nSatIndex, nLastSectID);
@ -303,6 +336,9 @@ void CCompoundFile::AddSiblings(VECTOR<int>& arIndexs, int nCurrentIndex)
if (arIndexs.end() == itFoundIndex)
arIndexs.push_back(nCurrentIndex);
if (nCurrentIndex >= m_arDirectoryEntries.size())
return;
const int nLeftSibling = m_arDirectoryEntries.size() > nCurrentIndex ? m_arDirectoryEntries.at(nCurrentIndex)->GetLeftSiblingID() : -1;
const int nRightSibling = m_arDirectoryEntries.size() > nCurrentIndex ? m_arDirectoryEntries.at(nCurrentIndex)->GetRightSiblingID() : -1;
@ -335,6 +371,9 @@ VECTOR<int> CCompoundFile::GetSecIDsFromSAT(int nSecID, int nSatIndex, int nSecI
m_fFile.seekg((nSecID + 1) * m_nSectorSize);
m_fFile.read(oBuffer.GetCurPtr(), m_nSectorSize);
if (m_fFile.gcount() != m_nSectorSize)
return VECTOR<int>();
int nCurrSecID = nSecIDSSAT;
VECTOR<int> arSecIDs;
@ -475,8 +514,8 @@ void CCompoundFile::ParseDirectorySector(CHWPStream& oBuffer)
STRING sDirectiryEnryName;
oBuffer.ReadShort(shEntryNameLen);
oBuffer.MoveTo(64 + nIndex);
oBuffer.ReadString(sDirectiryEnryName, shEntryNameLen);
oBuffer.MoveTo(nIndex);
oBuffer.ReadString(sDirectiryEnryName, shEntryNameLen, EStringCharacter::UTF16);
oBuffer.MoveTo(66 + nIndex);
//
int nObjectType = oBuffer.ReadByte() & 0xFF;
@ -487,21 +526,21 @@ void CCompoundFile::ParseDirectorySector(CHWPStream& oBuffer)
oBuffer.ReadInt(nRightSiblingID);
oBuffer.ReadInt(nChildID);
long lClsID1, lClsID2;
long long lClsID1, lClsID2;
oBuffer.ReadLong(lClsID1);
oBuffer.ReadLong(lClsID2);
int nStateBit;
oBuffer.ReadInt(nStateBit);
long lCreationTime, lModifiedTime;
long long lCreationTime, lModifiedTime;
oBuffer.ReadLong(lCreationTime);
oBuffer.ReadLong(lModifiedTime);
int nStartingSectorID;
oBuffer.ReadInt(nStartingSectorID);
long lStreamSize;
long long lStreamSize;
oBuffer.ReadLong(lStreamSize);
CDirectoryEntry *pDirectoryEntry = new CDirectoryEntry();
@ -574,9 +613,9 @@ bool CCompoundFile::ParseHeader(CHWPStream& oBuffer)
if (0x0003 != m_nMajorVersion && 0x0004 != m_nMajorVersion)
return false;
int nByteOrder = oBuffer.ReadShort();
short shByteOrder = oBuffer.ReadShort();
if (0xFFFE != nByteOrder)
if (0xFFFE != (unsigned short)shByteOrder)
return false;
int nSectorShift = oBuffer.ReadShort();
@ -630,7 +669,9 @@ bool CCompoundFile::CheckSignature(CHWPStream& oBuffer)
return false;
BYTE arBufSig[8];
oBuffer.ReadBytes(arBufSig, 8);
if (!oBuffer.ReadBytes(arBufSig, 8))
return false;
if ((BYTE)0xD0 == arBufSig[0] && (BYTE)0xCF == arBufSig[1] && (BYTE)0x11 == arBufSig[2] && (BYTE)0xE0 == arBufSig[3] &&
(BYTE)0xA1 == arBufSig[4] && (BYTE)0xB1 == arBufSig[5] && (BYTE)0x1A == arBufSig[6] && (BYTE)0xE1 == arBufSig[7])

View File

@ -35,12 +35,12 @@ void CDirectoryEntry::SetChildID(int nChildID)
m_nChildID = nChildID;
}
void CDirectoryEntry::SetClsID1(const long& lClsID1)
void CDirectoryEntry::SetClsID1(const long long& lClsID1)
{
m_lClsID1 = lClsID1;
}
void CDirectoryEntry::SetClsID2(const long& lClsID2)
void CDirectoryEntry::SetClsID2(const long long& lClsID2)
{
m_lClsID2 = lClsID2;
}
@ -50,12 +50,12 @@ void CDirectoryEntry::SetStateBit(int nStateBit)
m_nStateBit = nStateBit;
}
void CDirectoryEntry::SetCreationTime(const long& lCreationTime)
void CDirectoryEntry::SetCreationTime(const long long& lCreationTime)
{
m_lCreationTime = lCreationTime;
}
void CDirectoryEntry::SetModifiedTime(const long& lModifiedTime)
void CDirectoryEntry::SetModifiedTime(const long long& lModifiedTime)
{
m_lModifiedTime = lModifiedTime;
}
@ -65,7 +65,7 @@ void CDirectoryEntry::SetStartingSectorID(int nStartingSectorID)
m_nStartingSectorID = nStartingSectorID;
}
void CDirectoryEntry::SetStreamSize(const long& lStreamSize)
void CDirectoryEntry::SetStreamSize(const long long& lStreamSize)
{
m_lStreamSize = lStreamSize;
}
@ -95,7 +95,7 @@ int CDirectoryEntry::GetStartingSectorID() const
return m_nStartingSectorID;
}
long CDirectoryEntry::GetStreamSize() const
long long CDirectoryEntry::GetStreamSize() const
{
return m_lStreamSize;
}
@ -109,4 +109,9 @@ VECTOR<int>& CDirectoryEntry::GetSecNums()
{
return m_arSecNums;
}
int CDirectoryEntry::GetObjectType() const
{
return m_nObjectType;
}
}

View File

@ -13,13 +13,13 @@ class CDirectoryEntry
int m_nLeftSiblingID;
int m_nRightSiblingID;
int m_nChildID;
long m_lClsID1;
long m_lClsID2;
long long m_lClsID1;
long long m_lClsID2;
int m_nStateBit;
long m_lCreationTime;
long m_lModifiedTime;
long long m_lCreationTime;
long long m_lModifiedTime;
int m_nStartingSectorID;
long m_lStreamSize;
long long m_lStreamSize;
VECTOR<int> m_arSecNums;
public:
CDirectoryEntry();
@ -30,19 +30,19 @@ public:
void SetLeftSiblingID(int nLeftSiblingID);
void SetRightSiblingID(int nRightSiblingID);
void SetChildID(int nChildID);
void SetClsID1(const long& lClsID1);
void SetClsID2(const long& lClsID2);
void SetClsID1(const long long& lClsID1);
void SetClsID2(const long long& lClsID2);
void SetStateBit(int nStateBit);
void SetCreationTime(const long& lCreationTime);
void SetModifiedTime(const long& lModifiedTime);
void SetCreationTime(const long long& lCreationTime);
void SetModifiedTime(const long long& lModifiedTime);
void SetStartingSectorID(int nStartingSectorID);
void SetStreamSize(const long& lStreamSize);
void SetStreamSize(const long long& lStreamSize);
int GetLeftSiblingID() const;
int GetRightSiblingID() const;
int GetChildID() const;
int GetStartingSectorID() const;
long GetStreamSize() const;
long long GetStreamSize() const;
VECTOR<int> GetSecNums() const;
VECTOR<int>& GetSecNums();

View File

@ -10,7 +10,7 @@ CCtrlClick::CCtrlClick(const STRING& sCtrlId, int nSize, CHWPStream& oBuffer, in
oBuffer.Skip(4);
oBuffer.Skip(1);
oBuffer.ReadString(m_sClickHereStr);
oBuffer.ReadString(m_sClickHereStr, EStringCharacter::UTF16);
oBuffer.Skip(4);
oBuffer.Skip(4);

View File

@ -127,7 +127,7 @@ namespace HWP
oBuffer.ReadInt(m_nBlockPageBreak);
if (nSize > (oBuffer.GetCurPtr() - pOldCurentPos))
oBuffer.ReadString(m_sObjDesc);
oBuffer.ReadString(m_sObjDesc, EStringCharacter::UTF16);
m_nSize = oBuffer.GetCurPtr() - pOldCurentPos;
}
@ -144,12 +144,13 @@ namespace HWP
int CCtrlCommon::ParseCtrl(CCtrlCommon& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
{
const STRING sCtrlId(oBuffer.GetCurPtr(), 4); //TODO:: StandardCharsets.US_ASCII
STRING sCtrlId;
oBuffer.ReadString(sCtrlId, 4, EStringCharacter::ASCII);
if ("nil$" == sCtrlId || "loc$" == sCtrlId || "cer$" == sCtrlId || "lle$" == sCtrlId ||
"cra$" == sCtrlId || "lop$" == sCtrlId || "ruc$" == sCtrlId || "deqe" == sCtrlId ||
"cip$" == sCtrlId || "elo$" == sCtrlId || "noc$" == sCtrlId || "div$" == sCtrlId ||
"tat$" == sCtrlId)
if (L"nil$" == sCtrlId || L"loc$" == sCtrlId || L"cer$" == sCtrlId || L"lle$" == sCtrlId ||
L"cra$" == sCtrlId || L"lop$" == sCtrlId || L"ruc$" == sCtrlId || L"deqe" == sCtrlId ||
L"cip$" == sCtrlId || L"elo$" == sCtrlId || L"noc$" == sCtrlId || L"div$" == sCtrlId ||
L"tat$" == sCtrlId)
return 4;
return 0;

View File

@ -12,7 +12,7 @@
namespace HWP
{
CCtrlContainer::CCtrlContainer(const std::string& sCtrlID)
CCtrlContainer::CCtrlContainer(const STRING& sCtrlID)
: CCtrlGeneralShape(sCtrlID)
{}
@ -22,7 +22,7 @@ CCtrlContainer::CCtrlContainer(const STRING& sCtrlID, int nSize, CHWPStream& oBu
CCtrlContainer::~CCtrlContainer()
{
for (CCtrlGeneralShape* pElement : m_arList)
for (CCtrlGeneralShape* pElement : m_arShapes)
{
if (nullptr != pElement)
delete pElement;
@ -31,17 +31,22 @@ CCtrlContainer::~CCtrlContainer()
void CCtrlContainer::AddShape(CCtrlGeneralShape* pShape)
{
m_arList.push_back(pShape);
m_arShapes.push_back(pShape);
}
bool CCtrlContainer::Empty() const
{
return m_arList.empty();
return m_arShapes.empty();
}
std::vector<CCtrlGeneralShape*> CCtrlContainer::GetShapes() const
{
return m_arShapes;
}
CCtrlGeneralShape* CCtrlContainer::GetLastShape()
{
return (!m_arList.empty()) ? m_arList.back() : nullptr;
return (!m_arShapes.empty()) ? m_arShapes.back() : nullptr;
}
int CCtrlContainer::ParseElement(CCtrlContainer& oObj, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
@ -56,9 +61,9 @@ int CCtrlContainer::ParseElement(CCtrlContainer& oObj, int nSize, CHWPStream& oB
oObj.m_arCtrlIdList.reserve(oObj.m_shNElement);
for (unsigned int unIndex = 0; unIndex < oObj.m_shNElement; ++unIndex)
oBuffer.ReadString(oObj.m_arCtrlIdList[unIndex], 4);
oBuffer.ReadString(oObj.m_arCtrlIdList[unIndex], 4, EStringCharacter::ASCII);
oObj.m_arList.reserve(oObj.m_shNElement);
oObj.m_arShapes.reserve(oObj.m_shNElement);
STRING sCtrlId;
@ -73,28 +78,28 @@ int CCtrlContainer::ParseElement(CCtrlContainer& oObj, int nSize, CHWPStream& oB
{
CCtrlGeneralShape* pChldObj = nullptr;
oBuffer.ReadString(sCtrlId, 4);
oBuffer.ReadString(sCtrlId, 4, EStringCharacter::ASCII);
if ("cip$" == sCtrlId)
if (L"cip$" == sCtrlId)
CREATE_OBJECT(CCtrlShapePic)
else if ("cer$" == sCtrlId)
else if (L"cer$" == sCtrlId)
CREATE_OBJECT(CCtrlShapeRect)
else if ("nil$" == sCtrlId)
else if (L"nil$" == sCtrlId)
CREATE_OBJECT(CCtrlShapeLine)
else if ("noc$" == sCtrlId)
else if (L"noc$" == sCtrlId)
CREATE_OBJECT(CCtrlContainer)
else if ("lle$" == sCtrlId)
else if (L"lle$" == sCtrlId)
CREATE_OBJECT(CCtrlShapeEllipse)
else if ("lop$" == sCtrlId)
else if (L"lop$" == sCtrlId)
CREATE_OBJECT(CCtrlShapePolygon)
else if ("cra$" == sCtrlId)
else if (L"cra$" == sCtrlId)
CREATE_OBJECT(CCtrlShapeArc)
else if ("ruc$" == sCtrlId)
else if (L"ruc$" == sCtrlId)
CREATE_OBJECT(CCtrlShapeCurve)
else if ("elo$" == sCtrlId)
else if (L"elo$" == sCtrlId)
CREATE_OBJECT(CCtrlShapeOle)
oObj.m_arList[unIndex] = pChldObj;
oObj.m_arShapes[unIndex] = pChldObj;
}
return oBuffer.GetCurPtr() - pOldCurentPos;
@ -111,23 +116,10 @@ int CCtrlContainer::ParseCtrl(CCtrlContainer& oObj, int nSize, CHWPStream& oBuff
oObj.m_arCtrlIdList.reserve(oObj.m_shNElement);
for (unsigned int unIndex = 0; unIndex < oObj.m_shNElement; ++unIndex)
oBuffer.ReadString(oObj.m_arCtrlIdList[unIndex], 4);
oBuffer.ReadString(oObj.m_arCtrlIdList[unIndex], 4, EStringCharacter::ASCII);
oBuffer.Skip(4);
return oBuffer.GetCurPtr() - pOldCurentPos;
}
template<typename FindClass>
FindClass* CCtrlContainer::FindLastElement()
{
for (VECTOR<CCtrlGeneralShape*>::const_reverse_iterator itCtrl = m_arList.crbegin(); itCtrl != m_arList.crend(); ++itCtrl)
{
if (nullptr != dynamic_cast<FindClass>(*itCtrl))
return (FindClass*)(*itCtrl);
}
return nullptr;
}
}

View File

@ -9,7 +9,7 @@ class CCtrlContainer : public CCtrlGeneralShape
{
short m_shNElement;
VECTOR<STRING> m_arCtrlIdList;
VECTOR<CCtrlGeneralShape*> m_arList;
VECTOR<CCtrlGeneralShape*> m_arShapes;
public:
CCtrlContainer(const STRING& sCtrlID);
CCtrlContainer(const STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
@ -17,8 +17,7 @@ public:
bool Empty() const;
template <typename FindClass>
FindClass* FindLastElement();
VECTOR<CCtrlGeneralShape*> GetShapes() const;
void AddShape(CCtrlGeneralShape* pShape);
CCtrlGeneralShape* GetLastShape();

View File

@ -20,16 +20,16 @@ int CCtrlEqEdit::ParseElement(CCtrlEqEdit& oObj, int nSize, CHWPStream& oBuffer,
oObj.m_bFullFilled = true;
oBuffer.ReadInt(oObj.m_nAttr);
oBuffer.ReadString(oObj.m_sEqn);
oBuffer.ReadString(oObj.m_sEqn, EStringCharacter::UTF16);
oBuffer.ReadInt(oObj.m_nCharSize);
oBuffer.ReadColor(oObj.m_nColor);
oBuffer.ReadInt(oObj.m_nBaseline);
oBuffer.ReadString(oObj.m_sVersion);
oBuffer.ReadString(oObj.m_sVersion, EStringCharacter::UTF16);
if (oBuffer.GetCurPtr() - pOldCurentPos +2 > nSize)
return nSize;
oBuffer.ReadString(oObj.m_sFont);
oBuffer.ReadString(oObj.m_sFont, EStringCharacter::UTF16);
return nSize;
}

View File

@ -52,7 +52,7 @@ CCtrlGeneralShape* CCtrlGeneralShape::Parse(CCtrlGeneralShape& oObj, int nSize,
oBuffer.SavePosition();
STRING sCtrlId;
oBuffer.ReadString(sCtrlId, 4);
oBuffer.ReadString(sCtrlId, 4, EStringCharacter::ASCII);
CCtrlGeneralShape *pShape = nullptr;
@ -64,52 +64,52 @@ CCtrlGeneralShape* CCtrlGeneralShape::Parse(CCtrlGeneralShape& oObj, int nSize,
else \
oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos())
if ("cip$" == sCtrlId)
if (L"cip$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapePic);
}
else if ("cer$" == sCtrlId)
else if (L"cer$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapeRect);
}
else if ("nil$" == sCtrlId ||
"loc$" == sCtrlId)
else if (L"nil$" == sCtrlId ||
L"loc$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapeLine);
}
else if ("noc$" == sCtrlId)
else if (L"noc$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlContainer);
}
else if ("lle$" == sCtrlId)
else if (L"lle$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapeEllipse);
}
else if ("lop$" == sCtrlId)
else if (L"lop$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapePolygon);
}
else if ("cra$" == sCtrlId)
else if (L"cra$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapeArc);
}
else if ("ruc$" == sCtrlId)
else if (L"ruc$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapeCurve);
}
else if ("deqe" == sCtrlId)
else if (L"deqe" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlEqEdit);
}
else if ("elo$" == sCtrlId)
else if (L"elo$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapeOle);
}
else if ("div$" == sCtrlId)
else if (L"div$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapeVideo);
}
else if ("tat$" == sCtrlId)
else if (L"tat$" == sCtrlId)
{
CREATE_AND_PARSE_SHAPE(CCtrlShapeTextArt);
}

View File

@ -39,10 +39,10 @@ CCtrlPageNumPos::CCtrlPageNumPos(const STRING& sCtrlID, int nSize, CHWPStream& o
m_ePos = GetNumPos((nAttr >> 8) & 0xF);
oBuffer.Skip(2);
oBuffer.ReadString(m_sUserDef, 2);
oBuffer.ReadString(m_sPrefix, 2);
oBuffer.ReadString(m_sPostfix, 2);
oBuffer.ReadString(m_sConstantDash, 2);
oBuffer.ReadString(m_sUserDef, 2, EStringCharacter::UTF16);
oBuffer.ReadString(m_sPrefix, 2, EStringCharacter::UTF16);
oBuffer.ReadString(m_sPostfix, 2, EStringCharacter::UTF16);
oBuffer.ReadString(m_sConstantDash, 2, EStringCharacter::UTF16);
m_nSize = oBuffer.GetCurPtr() - pOldCurrentPos;
}

View File

@ -64,7 +64,7 @@ int CCtrlShapeEllipse::ParseListHeaderAppend(CCtrlShapeEllipse& oObj, int nSize,
{
oBuffer.Skip(10);
STRING sFieldName;
oBuffer.ReadString(sFieldName);
oBuffer.ReadString(sFieldName, EStringCharacter::UTF16);
oBuffer.Skip(nSize - (oBuffer.GetCurPtr() - pOldCurrentPos));
}

View File

@ -17,7 +17,7 @@ int CCtrlShapeLine::ParseElement(CCtrlShapeLine& oObj, int nSize, CHWPStream& oB
{
BYTE* pOldCurrentPos = oBuffer.GetCurPtr();
if ("loc$" == oObj.GetID())
if (L"loc$" == oObj.GetID())
oBuffer.Skip(4);
oBuffer.ReadInt(oObj.m_nStartX);

View File

@ -18,7 +18,7 @@ int CCtrlShapeOle::ParseElement(CCtrlShapeOle& oObj, int nSize, CHWPStream& oBuf
oBuffer.ReadInt(oObj.m_nAttr);
oBuffer.ReadInt(oObj.m_nExtentX);
oBuffer.ReadInt(oObj.m_nExtentY);
oObj.m_sBinDataID = std::to_string(oBuffer.ReadShort());
oObj.m_sBinDataID = std::to_wstring(oBuffer.ReadShort());
oBuffer.ReadColor(oObj.m_nBorderColor);
oBuffer.ReadInt(oObj.m_nBorderThick);
oBuffer.ReadInt(oObj.m_nBorderAttr);

View File

@ -162,7 +162,7 @@ int CCtrlShapePic::ParseElement(CCtrlShapePic& oObj, int nSize, CHWPStream& oBuf
short shBinItemID;
oBuffer.ReadShort(shBinItemID);
oObj.m_sBinDataID = std::to_string(shBinItemID - 1);
oObj.m_sBinDataID = std::to_wstring(shBinItemID - 1);
oBuffer.ReadByte(oObj.m_chBorderAlpha);

View File

@ -58,8 +58,8 @@ int CCtrlShapePolygon::ParseListHeaderAppend(CCtrlShapePolygon& oObj, int nSize,
if (nSize > (oBuffer.GetCurPtr() - pOldCurentPos))
{
oBuffer.Skip(10);
STRING sFieldNmae;
oBuffer.ReadString(sFieldNmae);
STRING sFieldName;
oBuffer.ReadString(sFieldName, EStringCharacter::UTF16);
oBuffer.Skip(nSize - (oBuffer.GetCurPtr() - pOldCurentPos));
}

View File

@ -51,8 +51,8 @@ int CCtrlShapeRect::ParseListHeaderAppend(CCtrlShapeRect& oObj, int nSize, CHWPS
if (nSize > (oBuffer.GetCurPtr() - pOldCurentPos))
{
oBuffer.Skip(10);
STRING sFieldNmae;
oBuffer.ReadString(sFieldNmae);
STRING sFieldName;
oBuffer.ReadString(sFieldName, EStringCharacter::UTF16);
oBuffer.Skip(nSize - (oBuffer.GetCurPtr() - pOldCurentPos));
}

View File

@ -2,7 +2,7 @@
namespace HWP
{
CCtrlShapeVideo::CCtrlShapeVideo(const std::string& sCtrlID)
CCtrlShapeVideo::CCtrlShapeVideo(const STRING& sCtrlID)
: CCtrlGeneralShape(sCtrlID)
{}
@ -17,11 +17,11 @@ int CCtrlShapeVideo::ParseElement(CCtrlShapeVideo& oObj, int nSize, CHWPStream&
if (0 == oObj.m_nVideoType)
oBuffer.ReadShort(oObj.m_shVidoeBinID);
else if (1 == oObj.m_nVideoType)
oBuffer.ReadString(oObj.m_sObjDesc);
oBuffer.ReadString(oObj.m_sObjDesc, EStringCharacter::UTF16);
short m_sBinID;
oBuffer.ReadShort(m_sBinID);
oObj.m_sThumnailBinID = std::to_string(m_sBinID - 1);
oObj.m_sThumnailBinID = std::to_wstring(m_sBinID - 1);
return nSize;
}

View File

@ -108,7 +108,7 @@ int CHWPPargraph::Parse(CHWPPargraph& oPara, int nSize, CHWPStream& oBuffer, int
return nSize;
}
CCtrl* CHWPPargraph::FindFirstElement(const std::string& sID, bool bFullfilled, unsigned int& nIndex) const
CCtrl* CHWPPargraph::FindFirstElement(const STRING& sID, bool bFullfilled, unsigned int& nIndex) const
{
nIndex = 0;
for (VECTOR<CCtrl*>::const_iterator itCtrl = m_arP.cbegin(); itCtrl != m_arP.cend(); ++itCtrl)
@ -121,18 +121,6 @@ CCtrl* CHWPPargraph::FindFirstElement(const std::string& sID, bool bFullfilled,
return nullptr;
}
template<typename FindClass>
FindClass* CHWPPargraph::FindLastElement()
{
for (VECTOR<CCtrl*>::const_reverse_iterator itCtrl = m_arP.crbegin(); itCtrl != m_arP.crend(); ++itCtrl)
{
if (nullptr != dynamic_cast<FindClass>(*itCtrl))
return (FindClass*)(*itCtrl);
}
return nullptr;
}
CCtrl* CHWPPargraph::FindLastElement(const STRING& sID)
{
for (VECTOR<CCtrl*>::const_reverse_iterator itCtrl = m_arP.crbegin(); itCtrl != m_arP.crend(); ++itCtrl)

View File

@ -38,9 +38,6 @@ public:
static int Parse(CHWPPargraph& oPara, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
CCtrl* FindFirstElement(const STRING& sID, bool bFullfilled, unsigned int& nIndex) const;
template <typename FindClass>
FindClass* FindLastElement();
CCtrl* FindLastElement(const STRING& sID);
};
}

20
HwpFile/test/main.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "../HWPFile.h"
#include <iostream>
int main()
{
CHWPFile oFile(L"C:/ONLYOFFICE/Files/hwp/example.hwp");
if (oFile.Open())
{
std::cout << "Successful" << std::endl;
return 0;
}
else
{
std::cout << "Unsuccessful" << std::endl;
return -1;
}
oFile.Close();
}

20
HwpFile/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 += HWPFILE_USE_DYNAMIC_LIBRARY
SOURCES += main.cpp
CORE_ROOT_DIR = $$PWD/../../
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)
ADD_DEPENDENCY(kernel, UnicodeConverter, HWPFile)
DESTDIR = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX