This commit is contained in:
Elena.Subbotina
2022-10-27 17:13:55 +03:00
parent b28acbabe8
commit 0f9730814b
15 changed files with 431 additions and 295 deletions

View File

@ -1,35 +0,0 @@
SOURCES += \
$$PWD/RBTree/rbtree.cpp \
$$PWD/cfitem.cpp \
$$PWD/cfstorage.cpp \
$$PWD/cfstream.cpp \
$$PWD/compoundfile.cpp \
$$PWD/directoryentry.cpp \
$$PWD/header.cpp \
$$PWD/sector.cpp \
$$PWD/sectorcollection.cpp \
$$PWD/stream.cpp \
$$PWD/streamrw.cpp \
$$PWD/streamview.cpp
HEADERS += \
$$PWD/RBTree/irbnode.h \
$$PWD/RBTree/rbtree.h \
$$PWD/RBTree/rbtreeexception.h \
$$PWD/cfexception.h \
$$PWD/cfitem.h \
$$PWD/cfstorage.h \
$$PWD/cfstream.h \
$$PWD/compoundfile.h \
$$PWD/directoryentry.h \
$$PWD/event.h \
$$PWD/guid.h \
$$PWD/header.h \
$$PWD/idirectoryentry.h \
$$PWD/sector.h \
$$PWD/sectorcollection.h \
$$PWD/slist.h \
$$PWD/stream.h \
$$PWD/streamrw.h \
$$PWD/streamview.h \
$$PWD/svector.h

49
Common/cfcpp/cfcpp.pro Normal file
View File

@ -0,0 +1,49 @@
QT -= core gui
TARGET = CompaundLib
TEMPLATE = lib
CONFIG += staticlib
CORE_ROOT_DIR = $$PWD/../..
PWD_ROOT_DIR = $$PWD
CONFIG += core_x2t
include(../base.pri)
SOURCES += \
RBTree/rbtree.cpp \
cfitem.cpp \
cfstorage.cpp \
cfstream.cpp \
compoundfile.cpp \
directoryentry.cpp \
header.cpp \
sector.cpp \
sectorcollection.cpp \
stream.cpp \
streamrw.cpp \
streamview.cpp
HEADERS += \
RBTree/irbnode.h \
RBTree/rbtree.h \
RBTree/rbtreeexception.h \
cfexception.h \
cfitem.h \
cfstorage.h \
cfstream.h \
compoundfile.h \
compoundfile_impl.h \
directoryentry.h \
event.h \
guid.h \
header.h \
idirectoryentry.h \
sector.h \
sectorcollection.h \
slist.h \
stream.h \
streamrw.h \
streamview.h \
svector.h

View File

@ -31,7 +31,7 @@
*/ */
#include "cfitem.h" #include "cfitem.h"
#include "idirectoryentry.h" #include "idirectoryentry.h"
#include "compoundfile.h" #include "compoundfile_impl.h"
#include <cstring> #include <cstring>

View File

@ -34,7 +34,7 @@
#include "cfexception.h" // Used by heirs #include "cfexception.h" // Used by heirs
#include <memory> #include <memory>
#include <string> #include <string>
#include "../../DesktopEditor/common/Types.h"
namespace CFCPP namespace CFCPP
{ {
@ -45,7 +45,7 @@ struct DataTime
char data[8] = {0,0,0,0,0,0,0,0}; char data[8] = {0,0,0,0,0,0,0,0};
}; };
class CompoundFile; class CompoundFile_impl;
class IDirectoryEntry; class IDirectoryEntry;
class CFItem : public std::enable_shared_from_this<CFItem> class CFItem : public std::enable_shared_from_this<CFItem>
@ -73,18 +73,18 @@ public:
void setDirEntry(const std::weak_ptr<IDirectoryEntry> &newDirEntry); void setDirEntry(const std::weak_ptr<IDirectoryEntry> &newDirEntry);
std::shared_ptr<IDirectoryEntry> getDirEntry() const; std::shared_ptr<IDirectoryEntry> getDirEntry() const;
friend class CompoundFile; friend class CompoundFile_impl;
protected: protected:
std::weak_ptr<IDirectoryEntry> dirEntry; std::weak_ptr<IDirectoryEntry> dirEntry;
CompoundFile* compoundFile = nullptr; CompoundFile_impl* compoundFile = nullptr;
protected: protected:
CFItem() {}; CFItem() {};
CFItem(CompoundFile* compoundFile) : CFItem(CompoundFile_impl* compoundFile) :
compoundFile(compoundFile) compoundFile(compoundFile)
{} {}
inline CompoundFile* getCompoundFile() inline CompoundFile_impl* getCompoundFile()
{return compoundFile;} {return compoundFile;}
void CheckDisposed() const; void CheckDisposed() const;
}; };

View File

@ -31,7 +31,7 @@
*/ */
#include "cfstorage.h" #include "cfstorage.h"
#include "cfexception.h" #include "cfexception.h"
#include "compoundfile.h" #include "compoundfile_impl.h"
#include "directoryentry.h" #include "directoryentry.h"
#include "RBTree/rbtreeexception.h" #include "RBTree/rbtreeexception.h"
#include "RBTree/irbnode.h" #include "RBTree/irbnode.h"
@ -40,7 +40,7 @@ using namespace CFCPP;
using RedBlackTree::RBTree; using RedBlackTree::RBTree;
CFStorage::CFStorage(CompoundFile *compFile, const std::weak_ptr<IDirectoryEntry> &dirEntry) : CFStorage::CFStorage(CompoundFile_impl *compFile, const std::weak_ptr<IDirectoryEntry> &dirEntry) :
CFItem(compFile) CFItem(compFile)
{ {
setDirEntry(dirEntry); setDirEntry(dirEntry);
@ -54,7 +54,7 @@ std::shared_ptr<RBTree> CFStorage::getChildren()
if (children == nullptr) if (children == nullptr)
{ {
children = CompoundFile::CreateNewTree(); children = CompoundFile_impl::CreateNewTree();
} }
} }
return children; return children;

View File

@ -38,11 +38,11 @@
namespace CFCPP namespace CFCPP
{ {
class CompoundFile_impl;
class CFStorage : public CFItem class CFStorage : public CFItem
{ {
public: public:
CFStorage(CompoundFile* compFile, const std::weak_ptr<IDirectoryEntry> &dirEntry); CFStorage(CompoundFile_impl* compFile, const std::weak_ptr<IDirectoryEntry> &dirEntry);
std::shared_ptr<RedBlackTree::RBTree> getChildren(); std::shared_ptr<RedBlackTree::RBTree> getChildren();
std::shared_ptr<CFStream> AddStream(const std::wstring& streamName); std::shared_ptr<CFStream> AddStream(const std::wstring& streamName);

View File

@ -32,11 +32,11 @@
#include "cfstream.h" #include "cfstream.h"
#include "cfexception.h" #include "cfexception.h"
#include "idirectoryentry.h" #include "idirectoryentry.h"
#include "compoundfile.h" #include "compoundfile_impl.h"
using namespace CFCPP; using namespace CFCPP;
CFStream::CFStream(CompoundFile* compFile, std::weak_ptr<IDirectoryEntry> dirEntry) : CFStream::CFStream(CompoundFile_impl* compFile, std::weak_ptr<IDirectoryEntry> dirEntry) :
CFItem(compFile) CFItem(compFile)
{ {
if (dirEntry.expired() || dirEntry.lock()->getSid() < 0) if (dirEntry.expired() || dirEntry.lock()->getSid() < 0)

View File

@ -41,7 +41,7 @@ namespace CFCPP
class CFStream : public CFItem class CFStream : public CFItem
{ {
public: public:
CFStream(CompoundFile* compFile, std::weak_ptr<IDirectoryEntry> dirEntry); CFStream(CompoundFile_impl* compFile, std::weak_ptr<IDirectoryEntry> dirEntry);
void Append(const std::vector<BYTE>& data); void Append(const std::vector<BYTE>& data);
void Write(const std::vector<BYTE>& data, std::streamsize position); void Write(const std::vector<BYTE>& data, std::streamsize position);

View File

@ -29,9 +29,7 @@
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
* *
*/ */
#include "compoundfile.h" #include "compoundfile_impl.h"
#include "cfstorage.h"
#include "header.h"
#include "directoryentry.h" #include "directoryentry.h"
#include "cfexception.h" #include "cfexception.h"
#include "streamview.h" #include "streamview.h"
@ -42,14 +40,79 @@
#include "sector.h" #include "sector.h"
//--------------------------------------------------------------------------------
using namespace CFCPP; using namespace CFCPP;
CompoundFile::CompoundFile() : CompoundFile::CompoundFile() : _impl(new CFCPP::CompoundFile_impl())
CompoundFile(CFSVersion::Ver_3, CFSConfiguration::Default) {
}
CompoundFile::CompoundFile(const std::wstring &fileName, CFSUpdateMode updateMode, CFSConfiguration configParameters) :
_impl(new CFCPP::CompoundFile_impl(fileName, updateMode, configParameters))
{
}
CompoundFile::CompoundFile(CFSVersion cfsVersion, CFSConfiguration configFlags) :
_impl(new CFCPP::CompoundFile_impl(cfsVersion, configFlags))
{
}
CompoundFile::CompoundFile(const std::wstring &fileName) :
_impl(new CFCPP::CompoundFile_impl(fileName))
{
}
CompoundFile::CompoundFile(Stream stream) :
_impl(new CFCPP::CompoundFile_impl(stream))
{
}
std::shared_ptr<CFStorage> CompoundFile::RootStorage()
{
return _impl->RootStorage();
}
void CompoundFile::Save(std::wstring wFileName)
{
_impl->Save(wFileName);
}
void CompoundFile::Save(Stream stream)
{
_impl->Save(stream);
}
void CompoundFile::Commit(bool releaseMemory)
{
_impl->Commit(releaseMemory);
}
bool CompoundFile::HasSourceStream() const
{
return _impl->HasSourceStream();
}
bool CompoundFile::ValidationExceptionEnabled() const
{
return _impl->ValidationExceptionEnabled();
}
bool CompoundFile::IsClosed()const
{
return _impl->IsClosed();
}
void CompoundFile::Close()
{
_impl->Close();
}
std::vector<BYTE> CompoundFile::GetDataBySID(int sid)
{
return _impl->GetDataBySID(sid);
}
GUID CompoundFile::getGuidBySID(int sid)
{
return _impl->getGuidBySID(sid);
}
GUID CompoundFile::getGuidForStream(int sid)
{
return _impl->getGuidForStream(sid);
}
//--------------------------------------------------------------------------------
CompoundFile_impl::CompoundFile_impl() :
CompoundFile_impl(CFSVersion::Ver_3, CFSConfiguration::Default)
{} {}
CompoundFile::CompoundFile(const std::wstring &fileName, CFSUpdateMode updateMode, CFSConfiguration configParameters) CompoundFile_impl::CompoundFile_impl(const std::wstring &fileName, CFSUpdateMode updateMode, CFSConfiguration configParameters)
{ {
configuration = configParameters; configuration = configParameters;
isValidationExceptionEnabled = !(configParameters & CFSConfiguration::NoValidationException); isValidationExceptionEnabled = !(configParameters & CFSConfiguration::NoValidationException);
@ -63,7 +126,7 @@ CompoundFile::CompoundFile(const std::wstring &fileName, CFSUpdateMode updateMod
FAT_SECTOR_ENTRIES_COUNT = (GetSectorSize() / 4); FAT_SECTOR_ENTRIES_COUNT = (GetSectorSize() / 4);
} }
CompoundFile::CompoundFile(CFSVersion cfsVersion, CFSConfiguration configFlags) : header(new Header(cfsVersion)) CompoundFile_impl::CompoundFile_impl(CFSVersion cfsVersion, CFSConfiguration configFlags) : header(new Header(cfsVersion))
{ {
configuration = configFlags; configuration = configFlags;
@ -72,7 +135,7 @@ CompoundFile::CompoundFile(CFSVersion cfsVersion, CFSConfiguration configFlags)
if (cfsVersion == CFSVersion::Ver_4) if (cfsVersion == CFSVersion::Ver_4)
{ {
Ver3SizeLimitReached action = std::bind(&CompoundFile::OnSizeLimitReached, this); Ver3SizeLimitReached action = std::bind(&CompoundFile_impl::OnSizeLimitReached, this);
sectors.OnVer3SizeLimitReached += action; sectors.OnVer3SizeLimitReached += action;
} }
@ -86,7 +149,7 @@ CompoundFile::CompoundFile(CFSVersion cfsVersion, CFSConfiguration configFlags)
rootStorage.reset(new CFStorage(this, rootDir)); rootStorage.reset(new CFStorage(this, rootDir));
} }
CompoundFile::CompoundFile(const std::wstring &fileName) CompoundFile_impl::CompoundFile_impl(const std::wstring &fileName)
{ {
sectorRecycle = false; sectorRecycle = false;
updateMode = CFSUpdateMode::ReadOnly; updateMode = CFSUpdateMode::ReadOnly;
@ -98,7 +161,7 @@ CompoundFile::CompoundFile(const std::wstring &fileName)
FAT_SECTOR_ENTRIES_COUNT = (GetSectorSize() / 4); FAT_SECTOR_ENTRIES_COUNT = (GetSectorSize() / 4);
} }
CompoundFile::CompoundFile(Stream stream) CompoundFile_impl::CompoundFile_impl(Stream stream)
{ {
LoadStream(stream); LoadStream(stream);
@ -106,7 +169,7 @@ CompoundFile::CompoundFile(Stream stream)
FAT_SECTOR_ENTRIES_COUNT = (GetSectorSize() / 4); FAT_SECTOR_ENTRIES_COUNT = (GetSectorSize() / 4);
} }
void CompoundFile::OnSizeLimitReached() void CompoundFile_impl::OnSizeLimitReached()
{ {
std::shared_ptr<Sector> rangeLockSector(new Sector(GetSectorSize(), sourceStream)); std::shared_ptr<Sector> rangeLockSector(new Sector(GetSectorSize(), sourceStream));
sectors.Add(rangeLockSector); sectors.Add(rangeLockSector);
@ -118,7 +181,7 @@ void CompoundFile::OnSizeLimitReached()
} }
void CompoundFile::Commit(bool releaseMemory) void CompoundFile_impl::Commit(bool releaseMemory)
{ {
if (isDisposed) if (isDisposed)
throw CFDisposedException("Compound File closed: cannot commit data"); throw CFDisposedException("Compound File closed: cannot commit data");
@ -177,27 +240,27 @@ void CompoundFile::Commit(bool releaseMemory)
sourceStream->flush(); sourceStream->flush();
} }
bool CompoundFile::HasSourceStream() const bool CompoundFile_impl::HasSourceStream() const
{ {
return sourceStream != nullptr; return sourceStream != nullptr;
} }
bool CompoundFile::ValidationExceptionEnabled() const bool CompoundFile_impl::ValidationExceptionEnabled() const
{ {
return isValidationExceptionEnabled; return isValidationExceptionEnabled;
} }
void CompoundFile::Close() void CompoundFile_impl::Close()
{ {
Close(true); Close(true);
} }
std::shared_ptr<RedBlackTree::RBTree> CompoundFile::CreateNewTree() std::shared_ptr<RedBlackTree::RBTree> CompoundFile_impl::CreateNewTree()
{ {
return std::shared_ptr<RedBlackTree::RBTree>(new RedBlackTree::RBTree); return std::shared_ptr<RedBlackTree::RBTree>(new RedBlackTree::RBTree);
} }
std::shared_ptr<RedBlackTree::RBTree> CompoundFile::GetChildrenTree(int sid) std::shared_ptr<RedBlackTree::RBTree> CompoundFile_impl::GetChildrenTree(int sid)
{ {
std::shared_ptr<RedBlackTree::RBTree> bst(new RedBlackTree::RBTree()); std::shared_ptr<RedBlackTree::RBTree> bst(new RedBlackTree::RBTree());
@ -206,12 +269,12 @@ std::shared_ptr<RedBlackTree::RBTree> CompoundFile::GetChildrenTree(int sid)
return bst; return bst;
} }
bool CompoundFile::IsClosed() const bool CompoundFile_impl::IsClosed() const
{ {
return isDisposed; return isDisposed;
} }
void CompoundFile::Load(Stream stream) void CompoundFile_impl::Load(Stream stream)
{ {
try try
{ {
@ -250,7 +313,7 @@ void CompoundFile::Load(Stream stream)
} }
} }
void CompoundFile::Save(std::wstring wFileName) void CompoundFile_impl::Save(std::wstring wFileName)
{ {
if (isDisposed) if (isDisposed)
throw CFException("Compound File closed: cannot save data"); throw CFException("Compound File closed: cannot save data");
@ -281,7 +344,7 @@ void CompoundFile::Save(std::wstring wFileName)
} }
void CompoundFile::Save(Stream stream) void CompoundFile_impl::Save(Stream stream)
{ {
if (isDisposed) if (isDisposed)
throw CFDisposedException("Compound File closed: cannot save data"); throw CFDisposedException("Compound File closed: cannot save data");
@ -322,7 +385,7 @@ void CompoundFile::Save(Stream stream)
} }
} }
SVector<Sector> CompoundFile::GetFatSectorChain() SVector<Sector> CompoundFile_impl::GetFatSectorChain()
{ {
int N_HEADER_FAT_ENTRY = 109; int N_HEADER_FAT_ENTRY = 109;
@ -410,7 +473,7 @@ SVector<Sector> CompoundFile::GetFatSectorChain()
return result; return result;
} }
SVector<Sector> CompoundFile::GetDifatSectorChain() SVector<Sector> CompoundFile_impl::GetDifatSectorChain()
{ {
int validationCount = 0; int validationCount = 0;
@ -470,7 +533,7 @@ SVector<Sector> CompoundFile::GetDifatSectorChain()
return result; return result;
} }
SVector<Sector> CompoundFile::GetNormalSectorChain(int sectorID) SVector<Sector> CompoundFile_impl::GetNormalSectorChain(int sectorID)
{ {
SVector<Sector> result; SVector<Sector> result;
@ -515,7 +578,7 @@ SVector<Sector> CompoundFile::GetNormalSectorChain(int sectorID)
return result; return result;
} }
SVector<Sector> CompoundFile::GetMiniSectorChain(int sectorID) SVector<Sector> CompoundFile_impl::GetMiniSectorChain(int sectorID)
{ {
SVector<Sector> result; SVector<Sector> result;
@ -561,7 +624,7 @@ SVector<Sector> CompoundFile::GetMiniSectorChain(int sectorID)
return result; return result;
} }
SVector<Sector> CompoundFile::GetSectorChain(int sectorID, SectorType chainType) SVector<Sector> CompoundFile_impl::GetSectorChain(int sectorID, SectorType chainType)
{ {
switch (chainType) switch (chainType)
{ {
@ -582,7 +645,7 @@ SVector<Sector> CompoundFile::GetSectorChain(int sectorID, SectorType chainType)
} }
} }
void CompoundFile::EnsureUniqueSectorIndex(int nextSectorID, std::unordered_set<int>& processedSectors) void CompoundFile_impl::EnsureUniqueSectorIndex(int nextSectorID, std::unordered_set<int>& processedSectors)
{ {
if (processedSectors.find(nextSectorID) != processedSectors.end() && this->isValidationExceptionEnabled) if (processedSectors.find(nextSectorID) != processedSectors.end() && this->isValidationExceptionEnabled)
{ {
@ -592,7 +655,7 @@ void CompoundFile::EnsureUniqueSectorIndex(int nextSectorID, std::unordered_set<
processedSectors.insert(nextSectorID); processedSectors.insert(nextSectorID);
} }
void CompoundFile::CommitDirectory() void CompoundFile_impl::CommitDirectory()
{ {
const int DIRECTORY_SIZE = 128; const int DIRECTORY_SIZE = 128;
@ -644,25 +707,25 @@ void CompoundFile::CommitDirectory()
} }
} }
void CompoundFile::Close(bool closeStream) void CompoundFile_impl::Close(bool closeStream)
{ {
this->closeStream = closeStream; this->closeStream = closeStream;
Dispose(closeStream); Dispose(closeStream);
} }
std::shared_ptr<IDirectoryEntry> CompoundFile::RootEntry() std::shared_ptr<IDirectoryEntry> CompoundFile_impl::RootEntry()
{ {
if (directoryEntries.empty()) if (directoryEntries.empty())
return {}; return {};
return directoryEntries[0]; return directoryEntries[0];
} }
std::shared_ptr<CFStorage> CompoundFile::RootStorage() std::shared_ptr<CFStorage> CompoundFile_impl::RootStorage()
{ {
return rootStorage; return rootStorage;
} }
SVector<IDirectoryEntry> CompoundFile::FindDirectoryEntries(std::wstring entryName) SVector<IDirectoryEntry> CompoundFile_impl::FindDirectoryEntries(std::wstring entryName)
{ {
SVector<IDirectoryEntry> result; SVector<IDirectoryEntry> result;
@ -675,7 +738,7 @@ SVector<IDirectoryEntry> CompoundFile::FindDirectoryEntries(std::wstring entryNa
return result; return result;
} }
std::shared_ptr<RedBlackTree::RBTree> CompoundFile::DoLoadChildrenTrusted(std::shared_ptr<IDirectoryEntry> de) std::shared_ptr<RedBlackTree::RBTree> CompoundFile_impl::DoLoadChildrenTrusted(std::shared_ptr<IDirectoryEntry> de)
{ {
std::shared_ptr<RedBlackTree::RBTree> bst; std::shared_ptr<RedBlackTree::RBTree> bst;
@ -687,7 +750,7 @@ std::shared_ptr<RedBlackTree::RBTree> CompoundFile::DoLoadChildrenTrusted(std::s
return bst; return bst;
} }
void CompoundFile::DoLoadChildren(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de) void CompoundFile_impl::DoLoadChildren(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de)
{ {
if (de->getChild() != DirectoryEntry::NOSTREAM) if (de->getChild() != DirectoryEntry::NOSTREAM)
{ {
@ -699,14 +762,14 @@ void CompoundFile::DoLoadChildren(std::shared_ptr<RedBlackTree::RBTree> bst, std
} }
} }
void CompoundFile::NullifyChildNodes(std::shared_ptr<IDirectoryEntry> de) void CompoundFile_impl::NullifyChildNodes(std::shared_ptr<IDirectoryEntry> de)
{ {
de->setParent({}); de->setParent({});
de->setLeft({}); de->setLeft({});
de->setRight({}); de->setRight({});
} }
void CompoundFile::LoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de) void CompoundFile_impl::LoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de)
{ {
levelSIDs.clear(); levelSIDs.clear();
@ -722,7 +785,7 @@ void CompoundFile::LoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std::
} }
} }
void CompoundFile::DoLoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de) void CompoundFile_impl::DoLoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de)
{ {
if (ValidateSibling(de->getLeftSibling())) if (ValidateSibling(de->getLeftSibling()))
{ {
@ -740,7 +803,7 @@ void CompoundFile::DoLoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std
bst->Insert(de); bst->Insert(de);
} }
bool CompoundFile::ValidateSibling(int sid) bool CompoundFile_impl::ValidateSibling(int sid)
{ {
if (sid != DirectoryEntry::NOSTREAM) if (sid != DirectoryEntry::NOSTREAM)
{ {
@ -785,7 +848,7 @@ bool CompoundFile::ValidateSibling(int sid)
return false; return false;
} }
void CompoundFile::LoadDirectories() void CompoundFile_impl::LoadDirectories()
{ {
SVector<Sector> directoryChain SVector<Sector> directoryChain
= GetSectorChain(header->firstDirectorySectorID, SectorType::Normal); = GetSectorChain(header->firstDirectorySectorID, SectorType::Normal);
@ -808,12 +871,12 @@ void CompoundFile::LoadDirectories()
} }
} }
void CompoundFile::FreeMiniChain(SVector<Sector> &sectorChain, bool zeroSector) void CompoundFile_impl::FreeMiniChain(SVector<Sector> &sectorChain, bool zeroSector)
{ {
FreeMiniChain(sectorChain,0, zeroSector); FreeMiniChain(sectorChain,0, zeroSector);
} }
void CompoundFile::FreeMiniChain(SVector<Sector> &sectorChain, int nth_sector_to_remove, bool zeroSector) void CompoundFile_impl::FreeMiniChain(SVector<Sector> &sectorChain, int nth_sector_to_remove, bool zeroSector)
{ {
std::vector<char> ZEROED_MINI_SECTOR(Sector::MINISECTOR_SIZE, 0); std::vector<char> ZEROED_MINI_SECTOR(Sector::MINISECTOR_SIZE, 0);
@ -869,7 +932,7 @@ void CompoundFile::FreeMiniChain(SVector<Sector> &sectorChain, int nth_sector_to
} }
} }
void CompoundFile::FreeChain(SVector<Sector> &sectorChain, int nth_sector_to_remove, bool zeroSector) void CompoundFile_impl::FreeChain(SVector<Sector> &sectorChain, int nth_sector_to_remove, bool zeroSector)
{ {
SVector<Sector> FAT = GetSectorChain(-1, SectorType::FAT); SVector<Sector> FAT = GetSectorChain(-1, SectorType::FAT);
@ -901,12 +964,12 @@ void CompoundFile::FreeChain(SVector<Sector> &sectorChain, int nth_sector_to_rem
} }
} }
void CompoundFile::FreeChain(SVector<Sector> &sectorChain, bool zeroSector) void CompoundFile_impl::FreeChain(SVector<Sector> &sectorChain, bool zeroSector)
{ {
FreeChain(sectorChain, 0, zeroSector); FreeChain(sectorChain, 0, zeroSector);
} }
void CompoundFile::AllocateSectorChain(SVector<Sector> &sectorChain) void CompoundFile_impl::AllocateSectorChain(SVector<Sector> &sectorChain)
{ {
for (auto& sector : *sectorChain) for (auto& sector : *sectorChain)
{ {
@ -920,7 +983,7 @@ void CompoundFile::AllocateSectorChain(SVector<Sector> &sectorChain)
AllocateFATSectorChain(sectorChain); AllocateFATSectorChain(sectorChain);
} }
void CompoundFile::AllocateFATSectorChain(SVector<Sector> &sectorChain) void CompoundFile_impl::AllocateFATSectorChain(SVector<Sector> &sectorChain)
{ {
SVector<Sector> fatSectors = GetSectorChain(-1, SectorType::FAT); SVector<Sector> fatSectors = GetSectorChain(-1, SectorType::FAT);
@ -952,7 +1015,7 @@ void CompoundFile::AllocateFATSectorChain(SVector<Sector> &sectorChain)
AllocateDIFATSectorChain(fatStream.BaseSectorChain()); AllocateDIFATSectorChain(fatStream.BaseSectorChain());
} }
void CompoundFile::AllocateDIFATSectorChain(SVector<Sector> &FATsectorChain) void CompoundFile_impl::AllocateDIFATSectorChain(SVector<Sector> &FATsectorChain)
{ {
header->fatSectorsNumber = FATsectorChain.size(); header->fatSectorsNumber = FATsectorChain.size();
@ -1084,7 +1147,7 @@ void CompoundFile::AllocateDIFATSectorChain(SVector<Sector> &FATsectorChain)
header->fatSectorsNumber = fatSv.BaseSectorChain().size(); header->fatSectorsNumber = fatSv.BaseSectorChain().size();
} }
void CompoundFile::AllocateMiniSectorChain(SVector<Sector> &sectorChain) void CompoundFile_impl::AllocateMiniSectorChain(SVector<Sector> &sectorChain)
{ {
SVector<Sector> miniFAT SVector<Sector> miniFAT
= GetSectorChain(header->firstMiniFATSectorID, SectorType::Normal); = GetSectorChain(header->firstMiniFATSectorID, SectorType::Normal);
@ -1146,7 +1209,7 @@ void CompoundFile::AllocateMiniSectorChain(SVector<Sector> &sectorChain)
} }
} }
void CompoundFile::PersistMiniStreamToStream(const SVector<Sector> &miniSectorChain) void CompoundFile_impl::PersistMiniStreamToStream(const SVector<Sector> &miniSectorChain)
{ {
SVector<Sector> miniStream = GetSectorChain(RootEntry()->getStartSetc(), SectorType::Normal); SVector<Sector> miniStream = GetSectorChain(RootEntry()->getStartSetc(), SectorType::Normal);
@ -1169,12 +1232,12 @@ void CompoundFile::PersistMiniStreamToStream(const SVector<Sector> &miniSectorCh
} }
} }
int CompoundFile::LowSaturation(int x) int CompoundFile_impl::LowSaturation(int x)
{ {
return x > 0 ? x : 0; return x > 0 ? x : 0;
} }
void CompoundFile::SetSectorChain(SVector<Sector> sectorChain) void CompoundFile_impl::SetSectorChain(SVector<Sector> sectorChain)
{ {
if (sectorChain != nullptr && sectorChain.size() == 0) if (sectorChain != nullptr && sectorChain.size() == 0)
return; return;
@ -1191,17 +1254,17 @@ void CompoundFile::SetSectorChain(SVector<Sector> sectorChain)
} }
} }
CFSVersion CompoundFile::getVersion() const CFSVersion CompoundFile_impl::getVersion() const
{ {
return (CFSVersion)header->majorVersion; return (CFSVersion)header->majorVersion;
} }
SVector<IDirectoryEntry> &CompoundFile::GetDirectories() SVector<IDirectoryEntry> &CompoundFile_impl::GetDirectories()
{ {
return directoryEntries; return directoryEntries;
} }
void CompoundFile::ResetDirectoryEntry(int sid) void CompoundFile_impl::ResetDirectoryEntry(int sid)
{ {
directoryEntries[sid]->SetEntryName(L""); directoryEntries[sid]->SetEntryName(L"");
directoryEntries[sid]->setLeft({}); directoryEntries[sid]->setLeft({});
@ -1217,7 +1280,7 @@ void CompoundFile::ResetDirectoryEntry(int sid)
directoryEntries[sid]->setModifyDate(0); directoryEntries[sid]->setModifyDate(0);
} }
void CompoundFile::InvalidateDirectoryEntry(int sid) void CompoundFile_impl::InvalidateDirectoryEntry(int sid)
{ {
if (sid >= (int)directoryEntries.size()) if (sid >= (int)directoryEntries.size())
throw CFException("Invalid SID of the directory entry to remove"); throw CFException("Invalid SID of the directory entry to remove");
@ -1225,7 +1288,7 @@ void CompoundFile::InvalidateDirectoryEntry(int sid)
ResetDirectoryEntry(sid); ResetDirectoryEntry(sid);
} }
void CompoundFile::FreeAssociatedData(int sid) void CompoundFile_impl::FreeAssociatedData(int sid)
{ {
if (directoryEntries[sid]->getSize() > 0) if (directoryEntries[sid]->getSize() > 0)
{ {
@ -1244,7 +1307,7 @@ void CompoundFile::FreeAssociatedData(int sid)
} }
} }
void CompoundFile::FreeData(CFStream *stream) void CompoundFile_impl::FreeData(CFStream *stream)
{ {
if (stream == nullptr || stream->size() == 0) if (stream == nullptr || stream->size() == 0)
return; return;
@ -1266,22 +1329,22 @@ void CompoundFile::FreeData(CFStream *stream)
stream->dirEntry.lock()->setSize(0); stream->dirEntry.lock()->setSize(0);
} }
void CompoundFile::WriteData(std::shared_ptr<CFItem> cfItem, std::streamsize position, const std::vector<BYTE> &buffer) void CompoundFile_impl::WriteData(std::shared_ptr<CFItem> cfItem, std::streamsize position, const std::vector<BYTE> &buffer)
{ {
WriteData(cfItem, buffer, position, 0, buffer.size()); WriteData(cfItem, buffer, position, 0, buffer.size());
} }
void CompoundFile::WriteData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE> &buffer) void CompoundFile_impl::WriteData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE> &buffer)
{ {
WriteData(cfItem, 0, buffer); WriteData(cfItem, 0, buffer);
} }
void CompoundFile::AppendData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE> &buffer) void CompoundFile_impl::AppendData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE> &buffer)
{ {
WriteData(cfItem, cfItem->size(), buffer); WriteData(cfItem, cfItem->size(), buffer);
} }
void CompoundFile::SetStreamLength(std::shared_ptr<CFItem> cfItem, std::streamsize length) void CompoundFile_impl::SetStreamLength(std::shared_ptr<CFItem> cfItem, std::streamsize length)
{ {
if (cfItem->size() == length) if (cfItem->size() == length)
return; return;
@ -1433,7 +1496,7 @@ void CompoundFile::SetStreamLength(std::shared_ptr<CFItem> cfItem, std::streamsi
std::array<char, 256> buf; std::array<char, 256> buf;
buf.fill(0); buf.fill(0);
std::streamsize toRead = std::min(length, cfItem->size()); ULONG64 toRead = (ULONG64)(std::min)((ULONG64)length, cfItem->size());
while (toRead > count) while (toRead > count)
{ {
@ -1462,7 +1525,7 @@ void CompoundFile::SetStreamLength(std::shared_ptr<CFItem> cfItem, std::streamsi
} }
} }
SList<Sector> CompoundFile::FindFreeSectors(SectorType sType) SList<Sector> CompoundFile_impl::FindFreeSectors(SectorType sType)
{ {
SList<Sector> freeList; SList<Sector> freeList;
SList<Sector> zeroQueue; SList<Sector> zeroQueue;
@ -1532,7 +1595,7 @@ SList<Sector> CompoundFile::FindFreeSectors(SectorType sType)
return freeList; return freeList;
} }
std::vector<BYTE> CompoundFile::GetData(const CFStream *cFStream) std::vector<BYTE> CompoundFile_impl::GetData(const CFStream *cFStream)
{ {
if (isDisposed) if (isDisposed)
throw CFDisposedException("Compound File closed: cannot access data"); throw CFDisposedException("Compound File closed: cannot access data");
@ -1568,7 +1631,7 @@ std::vector<BYTE> CompoundFile::GetData(const CFStream *cFStream)
return result; return result;
} }
int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::vector<BYTE> &buffer, int count) int CompoundFile_impl::ReadData(CFStream *cFStream, std::streamsize position, std::vector<BYTE> &buffer, int count)
{ {
if (count > (int)buffer.size()) if (count > (int)buffer.size())
throw std::invalid_argument("count parameter exceeds buffer size"); throw std::invalid_argument("count parameter exceeds buffer size");
@ -1596,7 +1659,7 @@ int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::ve
return result; return result;
} }
int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::vector<BYTE> &buffer, int offset, int count) int CompoundFile_impl::ReadData(CFStream *cFStream, std::streamsize position, std::vector<BYTE> &buffer, int offset, int count)
{ {
auto de = cFStream->dirEntry.lock(); auto de = cFStream->dirEntry.lock();
@ -1621,7 +1684,7 @@ int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::ve
return result; return result;
} }
std::vector<BYTE> CompoundFile::GetDataBySID(int sid) std::vector<BYTE> CompoundFile_impl::GetDataBySID(int sid)
{ {
if (isDisposed) if (isDisposed)
throw CFDisposedException("Compound File closed: cannot access data"); throw CFDisposedException("Compound File closed: cannot access data");
@ -1654,7 +1717,7 @@ std::vector<BYTE> CompoundFile::GetDataBySID(int sid)
return result; return result;
} }
GUID CompoundFile::getGuidBySID(int sid) GUID CompoundFile_impl::getGuidBySID(int sid)
{ {
if (isDisposed) if (isDisposed)
throw CFDisposedException("Compound File closed: cannot access data"); throw CFDisposedException("Compound File closed: cannot access data");
@ -1664,7 +1727,7 @@ GUID CompoundFile::getGuidBySID(int sid)
return de->getStorageCLSID(); return de->getStorageCLSID();
} }
GUID CompoundFile::getGuidForStream(int sid) GUID CompoundFile_impl::getGuidForStream(int sid)
{ {
if (isDisposed) if (isDisposed)
throw CFDisposedException("Compound File closed: cannot access data"); throw CFDisposedException("Compound File closed: cannot access data");
@ -1684,7 +1747,7 @@ GUID CompoundFile::getGuidForStream(int sid)
return guid; return guid;
} }
void CompoundFile::WriteData(std::shared_ptr<CFItem> cfItem, const char* data, std::streamsize position, int count) void CompoundFile_impl::WriteData(std::shared_ptr<CFItem> cfItem, const char* data, std::streamsize position, int count)
{ {
if (data == nullptr) if (data == nullptr)
throw CFInvalidOperation("Parameter [data] cannot be null"); throw CFInvalidOperation("Parameter [data] cannot be null");
@ -1721,17 +1784,17 @@ void CompoundFile::WriteData(std::shared_ptr<CFItem> cfItem, const char* data, s
} }
} }
void CompoundFile::WriteData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE> &buffer, std::streamsize position, int offset, int count) void CompoundFile_impl::WriteData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE> &buffer, std::streamsize position, int offset, int count)
{ {
WriteData(cfItem, reinterpret_cast<const char*>(buffer.data() + offset), position, count); WriteData(cfItem, reinterpret_cast<const char*>(buffer.data() + offset), position, count);
} }
int CompoundFile::GetSectorSize() int CompoundFile_impl::GetSectorSize()
{ {
return 2 << (header->sectorShift - 1); return 2 << (header->sectorShift - 1);
} }
void CompoundFile::Dispose(bool disposing) void CompoundFile_impl::Dispose(bool disposing)
{ {
try try
{ {
@ -1762,7 +1825,7 @@ void CompoundFile::Dispose(bool disposing)
} }
} }
void CompoundFile::CheckForLockSector() void CompoundFile_impl::CheckForLockSector()
{ {
if (transactionLockAdded && !isTransactionLockAllocated) if (transactionLockAdded && !isTransactionLockAllocated)
{ {
@ -1776,7 +1839,7 @@ void CompoundFile::CheckForLockSector()
} }
} }
void CompoundFile::LoadFile(std::wstring fileName) void CompoundFile_impl::LoadFile(std::wstring fileName)
{ {
SetFileName(fileName); SetFileName(fileName);
Stream fs; Stream fs;
@ -1796,7 +1859,7 @@ void CompoundFile::LoadFile(std::wstring fileName)
} }
} }
void CompoundFile::SetFileName(std::wstring fileName) void CompoundFile_impl::SetFileName(std::wstring fileName)
{ {
BYTE* pUtf8 = NULL; BYTE* pUtf8 = NULL;
LONG lLen = 0; LONG lLen = 0;
@ -1805,7 +1868,7 @@ void CompoundFile::SetFileName(std::wstring fileName)
delete [] pUtf8; delete [] pUtf8;
} }
void CompoundFile::LoadStream(Stream stream) void CompoundFile_impl::LoadStream(Stream stream)
{ {
if (stream.get() == nullptr) if (stream.get() == nullptr)
throw CFException("Stream parameter cannot be null"); throw CFException("Stream parameter cannot be null");

View File

@ -31,18 +31,10 @@
*/ */
#pragma once #pragma once
#include "sectorcollection.h"
#include "cfstorage.h" #include "cfstorage.h"
#include "slist.h"
#include <unordered_set>
#include "RBTree/rbtree.h"
#include "idirectoryentry.h"
#include <mutex>
#include "header.h"
namespace CFCPP namespace CFCPP
{ {
class DirectoryEntry;
enum CFSConfiguration enum CFSConfiguration
{ {
@ -59,6 +51,7 @@ enum CFSUpdateMode
Update Update
}; };
class CompoundFile_impl;
class CompoundFile class CompoundFile
{ {
public: public:
@ -68,14 +61,13 @@ public:
CompoundFile(Stream stream); CompoundFile(Stream stream);
CompoundFile(); CompoundFile();
~CompoundFile();
// Main methods
std::shared_ptr<CFStorage> RootStorage(); std::shared_ptr<CFStorage> RootStorage();
void Save(std::wstring wFileName); void Save(std::wstring wFileName);
void Save(Stream stream); void Save(Stream stream);
void Commit(bool releaseMemory = false); void Commit(bool releaseMemory = false);
bool HasSourceStream() const; bool HasSourceStream() const;
bool ValidationExceptionEnabled() const; bool ValidationExceptionEnabled() const;
@ -86,103 +78,7 @@ public:
GUID getGuidBySID(int sid); GUID getGuidBySID(int sid);
GUID getGuidForStream(int sid); GUID getGuidForStream(int sid);
// internal methods
static std::shared_ptr<RedBlackTree::RBTree> CreateNewTree();
std::shared_ptr<RedBlackTree::RBTree> GetChildrenTree(int sid);
SVector<IDirectoryEntry> &GetDirectories();
void ResetDirectoryEntry(int sid);
void InvalidateDirectoryEntry(int sid);
void FreeAssociatedData(int sid);
void FreeData(CFStream* stream);
void WriteData(std::shared_ptr<CFItem> cfItem, const char* data, std::streamsize position, int count);
void WriteData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE>& buffer, std::streamsize position, int offset, int count);
void WriteData(std::shared_ptr<CFItem> cfItem, std::streamsize position, const std::vector<BYTE>& buffer);
void WriteData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE>& buffer);
void AppendData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE>& buffer);
void SetStreamLength(std::shared_ptr<CFItem> cfItem, std::streamsize length);
SList<Sector> FindFreeSectors(SectorType sType);
std::vector<BYTE> GetData(const CFStream *cFStream);
int ReadData(CFStream* cFStream, std::streamsize position, std::vector<BYTE>& buffer, int count);
int ReadData(CFStream* cFStream, std::streamsize position, std::vector<BYTE>& buffer, int offset, int count);
protected:
int GetSectorSize();
void Dispose(bool disposing);
private: private:
void CheckForLockSector(); std::shared_ptr<CompoundFile_impl> _impl;
void OnSizeLimitReached();
void LoadFile(std::wstring fileName);
void SetFileName(std::wstring fileName);
void LoadStream(Stream stream);
void Load(Stream stream);
SVector<Sector> GetFatSectorChain();
SVector<Sector> GetDifatSectorChain();
SVector<Sector> GetNormalSectorChain(int sectorID);
SVector<Sector> GetMiniSectorChain(int sectorID);
SVector<Sector> GetSectorChain(int sectorID, SectorType chainType);
void EnsureUniqueSectorIndex(int nextsectorID, std::unordered_set<int> &processedSectors);
void CommitDirectory();
void Close(bool closeStream);
std::shared_ptr<IDirectoryEntry> RootEntry();
SVector<IDirectoryEntry> FindDirectoryEntries(std::wstring entryName);
std::shared_ptr<RedBlackTree::RBTree> DoLoadChildrenTrusted(std::shared_ptr<IDirectoryEntry> de);
void DoLoadChildren(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de);
void NullifyChildNodes(std::shared_ptr<IDirectoryEntry> de);
void LoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de);
void DoLoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de);
bool ValidateSibling(int sid);
void LoadDirectories();
void FreeMiniChain(SVector<Sector>& sectorChain, bool zeroSector);
void FreeMiniChain(SVector<Sector>& sectorChain, int nth_sector_to_remove, bool zeroSector);
void FreeChain(SVector<Sector>& sectorChain, int nth_sector_to_remove, bool zeroSector);
void FreeChain(SVector<Sector>& sectorChain, bool zeroSector);
void AllocateSectorChain(SVector<Sector>& sectorChain);
void AllocateFATSectorChain(SVector<Sector>& sectorChain);
void AllocateDIFATSectorChain(SVector<Sector>& FATsectorChain);
void AllocateMiniSectorChain(SVector<Sector>& sectorChain);
void PersistMiniStreamToStream(const SVector<Sector>& miniSectorChain);
static int LowSaturation(int x);
void SetSectorChain(SVector<Sector> sectorChain);
CFSVersion getVersion() const;
public:
CFSConfiguration configuration = Default;
std::unique_ptr<Header> header;
Stream sourceStream;
private:
const int HEADER_DIFAT_ENTRIES_COUNT = 109;
int DIFAT_SECTOR_FAT_ENTRIES_COUNT = 127;
int FAT_SECTOR_ENTRIES_COUNT = 128;
const int SIZE_OF_SID = 4;
bool sectorRecycle = false;
bool eraseFreeSectors = false;
static constexpr int FLUSHING_QUEUE_SIZE = 6000;
static constexpr int FLUSHING_BUFFER_MAX_SIZE = 1024 * 1024 * 16;
SectorCollection sectors;
std::fstream stream;
std::string fileName;
std::shared_ptr<CFStorage> rootStorage;
bool closeStream = true;
bool transactionLockAdded = false;
int lockSectorId = -1;
bool isTransactionLockAllocated = false;
bool isValidationExceptionEnabled = true;
bool isDisposed = false;
CFSUpdateMode updateMode;
SVector<IDirectoryEntry> directoryEntries;
std::list<int> levelSIDs;
std::mutex lockObject;
}; };
} }

View File

@ -0,0 +1,173 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
#pragma once
#include "compoundfile.h"
#include "sectorcollection.h"
#include "cfstorage.h"
#include "slist.h"
#include <unordered_set>
#include "RBTree/rbtree.h"
#include "idirectoryentry.h"
#include <mutex>
#include "header.h"
namespace CFCPP
{
class DirectoryEntry;
class CompoundFile_impl
{
public:
CompoundFile_impl(const std::wstring &fileName, CFSUpdateMode updateMode, CFSConfiguration configParameters = Default);
CompoundFile_impl(CFSVersion cfsVersion, CFSConfiguration configFlags);
CompoundFile_impl(const std::wstring &fileName);
CompoundFile_impl(Stream stream);
CompoundFile_impl();
// Main methods
std::shared_ptr<CFStorage> RootStorage();
void Save(std::wstring wFileName);
void Save(Stream stream);
void Commit(bool releaseMemory = false);
bool HasSourceStream() const;
bool ValidationExceptionEnabled() const;
bool IsClosed()const;
void Close();
std::vector<BYTE> GetDataBySID(int sid);
GUID getGuidBySID(int sid);
GUID getGuidForStream(int sid);
// internal methods
static std::shared_ptr<RedBlackTree::RBTree> CreateNewTree();
std::shared_ptr<RedBlackTree::RBTree> GetChildrenTree(int sid);
SVector<IDirectoryEntry> &GetDirectories();
void ResetDirectoryEntry(int sid);
void InvalidateDirectoryEntry(int sid);
void FreeAssociatedData(int sid);
void FreeData(CFStream* stream);
void WriteData(std::shared_ptr<CFItem> cfItem, const char* data, std::streamsize position, int count);
void WriteData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE>& buffer, std::streamsize position, int offset, int count);
void WriteData(std::shared_ptr<CFItem> cfItem, std::streamsize position, const std::vector<BYTE>& buffer);
void WriteData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE>& buffer);
void AppendData(std::shared_ptr<CFItem> cfItem, const std::vector<BYTE>& buffer);
void SetStreamLength(std::shared_ptr<CFItem> cfItem, std::streamsize length);
SList<Sector> FindFreeSectors(SectorType sType);
std::vector<BYTE> GetData(const CFStream *cFStream);
int ReadData(CFStream* cFStream, std::streamsize position, std::vector<BYTE>& buffer, int count);
int ReadData(CFStream* cFStream, std::streamsize position, std::vector<BYTE>& buffer, int offset, int count);
protected:
int GetSectorSize();
void Dispose(bool disposing);
private:
void CheckForLockSector();
void OnSizeLimitReached();
void LoadFile(std::wstring fileName);
void SetFileName(std::wstring fileName);
void LoadStream(Stream stream);
void Load(Stream stream);
SVector<Sector> GetFatSectorChain();
SVector<Sector> GetDifatSectorChain();
SVector<Sector> GetNormalSectorChain(int sectorID);
SVector<Sector> GetMiniSectorChain(int sectorID);
SVector<Sector> GetSectorChain(int sectorID, SectorType chainType);
void EnsureUniqueSectorIndex(int nextsectorID, std::unordered_set<int> &processedSectors);
void CommitDirectory();
void Close(bool closeStream);
std::shared_ptr<IDirectoryEntry> RootEntry();
SVector<IDirectoryEntry> FindDirectoryEntries(std::wstring entryName);
std::shared_ptr<RedBlackTree::RBTree> DoLoadChildrenTrusted(std::shared_ptr<IDirectoryEntry> de);
void DoLoadChildren(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de);
void NullifyChildNodes(std::shared_ptr<IDirectoryEntry> de);
void LoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de);
void DoLoadSiblings(std::shared_ptr<RedBlackTree::RBTree> bst, std::shared_ptr<IDirectoryEntry> de);
bool ValidateSibling(int sid);
void LoadDirectories();
void FreeMiniChain(SVector<Sector>& sectorChain, bool zeroSector);
void FreeMiniChain(SVector<Sector>& sectorChain, int nth_sector_to_remove, bool zeroSector);
void FreeChain(SVector<Sector>& sectorChain, int nth_sector_to_remove, bool zeroSector);
void FreeChain(SVector<Sector>& sectorChain, bool zeroSector);
void AllocateSectorChain(SVector<Sector>& sectorChain);
void AllocateFATSectorChain(SVector<Sector>& sectorChain);
void AllocateDIFATSectorChain(SVector<Sector>& FATsectorChain);
void AllocateMiniSectorChain(SVector<Sector>& sectorChain);
void PersistMiniStreamToStream(const SVector<Sector>& miniSectorChain);
static int LowSaturation(int x);
void SetSectorChain(SVector<Sector> sectorChain);
CFSVersion getVersion() const;
public:
CFSConfiguration configuration = Default;
std::unique_ptr<Header> header;
Stream sourceStream;
private:
const int HEADER_DIFAT_ENTRIES_COUNT = 109;
int DIFAT_SECTOR_FAT_ENTRIES_COUNT = 127;
int FAT_SECTOR_ENTRIES_COUNT = 128;
const int SIZE_OF_SID = 4;
bool sectorRecycle = false;
bool eraseFreeSectors = false;
static constexpr int FLUSHING_QUEUE_SIZE = 6000;
static constexpr int FLUSHING_BUFFER_MAX_SIZE = 1024 * 1024 * 16;
SectorCollection sectors;
std::fstream stream;
std::string fileName;
std::shared_ptr<CFStorage> rootStorage;
bool closeStream = true;
bool transactionLockAdded = false;
int lockSectorId = -1;
bool isTransactionLockAllocated = false;
bool isValidationExceptionEnabled = true;
bool isDisposed = false;
CFSUpdateMode updateMode;
SVector<IDirectoryEntry> directoryEntries;
std::list<int> levelSIDs;
std::mutex lockObject;
};
}

View File

@ -40,59 +40,58 @@
namespace CFCPP namespace CFCPP
{ {
class IStream class IStream
{ {
public: public:
virtual std::streamsize tell() = 0; virtual std::streamsize tell() = 0;
virtual std::streamsize seek(std::streamsize offset, std::ios_base::seekdir mode = std::ios::beg) = 0; virtual std::streamsize seek(std::streamsize offset, std::ios_base::seekdir mode = std::ios::beg) = 0;
virtual std::streamsize read(char* buffer, std::streamsize len) = 0; virtual std::streamsize read(char* buffer, std::streamsize len) = 0;
virtual void write (const char* buffer, std::streamsize len) = 0; virtual void write (const char* buffer, std::streamsize len) = 0;
virtual void flush() = 0; virtual void flush() = 0;
virtual void close() = 0; virtual void close() = 0;
}; };
using Stream = std::shared_ptr<IStream>; using Stream = std::shared_ptr<IStream>;
class FStreamWrapper : public IStream, public std::fstream class FStreamWrapper : public IStream, public std::fstream
{ {
public: public:
FStreamWrapper(std::string filename, std::ios_base::openmode openmode) : FStreamWrapper(std::string filename, std::ios_base::openmode openmode) :
std::fstream(filename, openmode) {} std::fstream(filename, openmode) {}
inline std::streamsize tell() override { inline std::streamsize tell() override {
return std::fstream::tellg(); return std::fstream::tellg();
} }
inline std::streamsize seek(std::streamsize offset, std::ios_base::seekdir mode = std::ios::beg) override { inline std::streamsize seek(std::streamsize offset, std::ios_base::seekdir mode = std::ios::beg) override {
std::fstream::seekp(offset, mode); std::fstream::seekp(offset, mode);
std::fstream::seekg(offset, mode); std::fstream::seekg(offset, mode);
return tell(); return tell();
} }
inline std::streamsize read(char* buffer, std::streamsize len) override { inline std::streamsize read(char* buffer, std::streamsize len) override {
std::fstream::read(buffer, len); std::fstream::read(buffer, len);
return tell(); return tell();
} }
inline void write (const char* buffer, std::streamsize len) override { inline void write (const char* buffer, std::streamsize len) override {
std::fstream::write(buffer, len); std::fstream::write(buffer, len);
} }
inline void flush() override { inline void flush() override {
std::fstream::flush(); std::fstream::flush();
} }
inline void close() override { inline void close() override {
std::fstream::close(); std::fstream::close();
} }
}; };
std::string CorrectUnixPath(const std::string original);
std::string CorrectUnixPath(const std::string original); Stream OpenFileStream(std::wstring filename, bool bRewrite = false, bool trunc = false);
Stream OpenFileStream(std::string filename, bool bRewrite = false, bool trunc = false);
Stream OpenFileStream(std::wstring filename, bool bRewrite = false, bool trunc = false); bool IsOpen(const Stream& st);
Stream OpenFileStream(std::string filename, bool bRewrite = false, bool trunc = false); std::streamsize Length(const Stream& st);
int FileLenght(std::wstring filename);
bool IsOpen(const Stream& st); ULONG64 FileFNVHash(std::wstring filename, int len = -1, int offset = 0);
std::streamsize Length(const Stream& st);
int FileLenght(std::wstring filename);
ULONG64 FileFNVHash(std::wstring filename, int len = -1, int offset = 0);
} }

View File

@ -42,6 +42,7 @@
#include "../../ASCOfficeDocFile/DocDocxConverter/MemoryStream.h" #include "../../ASCOfficeDocFile/DocDocxConverter/MemoryStream.h"
#include "simple_xml_writer.h" #include "simple_xml_writer.h"
#include "../../Common/cfcpp/compoundfile.h"
//CRYPT::_ecmaCryptData cryptDataGlobal; for Test //CRYPT::_ecmaCryptData cryptDataGlobal; for Test

View File

@ -94,6 +94,8 @@ LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lPPTXFormatLib
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lDocxFormatLib LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lDocxFormatLib
#xlsbformat #xlsbformat
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lXlsbFormatLib LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lXlsbFormatLib
#cf
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCompaundLib
#Crypto++ #Crypto++
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib

View File

@ -18,11 +18,7 @@ SUBDIRS = \
OdfFileReaderLib \ OdfFileReaderLib \
OdfFileWriterLib \ OdfFileWriterLib \
XlsFormatLib \ XlsFormatLib \
kernel \ CompaundLib \
HtmlFile2 \
EpubFile \
XpsFile \
doctrenderer \
X2tConverter X2tConverter
XlsbFormatLib.file = ../../../Common/DocxFormat/DocxFormatLib/XlsbFormatLib.pro XlsbFormatLib.file = ../../../Common/DocxFormat/DocxFormatLib/XlsbFormatLib.pro
@ -37,11 +33,7 @@ OdfFileReaderLib.file = ../../../ASCOfficeOdfFile/linux/OdfFileReaderLib.pro
OdfFileWriterLib.file = ../../../ASCOfficeOdfFileW/linux/OdfFileWriterLib.pro OdfFileWriterLib.file = ../../../ASCOfficeOdfFileW/linux/OdfFileWriterLib.pro
XlsFormatLib.file = ../../../ASCOfficeXlsFile2/source/linux/XlsFormatLib.pro XlsFormatLib.file = ../../../ASCOfficeXlsFile2/source/linux/XlsFormatLib.pro
VbaFormatLib.file = ../../../ASCOfficeXlsFile2/source/linux/VbaFormatLib.pro VbaFormatLib.file = ../../../ASCOfficeXlsFile2/source/linux/VbaFormatLib.pro
HtmlFile2.file = ../../../HtmlFile2/HtmlFile2.pro CompaundLib.file = ../../../Common/cfcpp/cfcpp.pro
EpubFile.file = ../../../EpubFile/CEpubFile.pro
XpsFile.file = ../../../XpsFile/XpsFile.pro
kernel.file = ../../../Common/kernel.pro
doctrenderer.file = ../../../DesktopEditor/doctrenderer/doctrenderer.pro
X2tConverter.depends = \ X2tConverter.depends = \
XlsbFormatLib \ XlsbFormatLib \
@ -56,11 +48,7 @@ X2tConverter.depends = \
OdfFileWriterLib \ OdfFileWriterLib \
VbaFormatLib \ VbaFormatLib \
XlsFormatLib \ XlsFormatLib \
kernel.pro \ CompaundLib
HtmlFile2 \
EpubFile \
XpsFile \
doctrenderer
# build the project sequentially as listed in SUBDIRS ! # build the project sequentially as listed in SUBDIRS !
CONFIG += ordered CONFIG += ordered