From 42b155cd92a87bd0478e64b5b037d1d3266ac409 Mon Sep 17 00:00:00 2001 From: Ivan Morozov Date: Fri, 22 Jul 2022 20:25:37 +0300 Subject: [PATCH] correct headers --- Common/cppcf/RBTree/rbtree.cpp | 2 +- Common/cppcf/RBTree/rbtree.h | 12 +- Common/cppcf/cfitem.cpp | 49 +++--- Common/cppcf/cfitem.h | 29 ++-- Common/cppcf/cfstorage.cpp | 86 ++++----- Common/cppcf/cfstorage.h | 7 +- Common/cppcf/cfstream.cpp | 26 +-- Common/cppcf/cfstream.h | 4 +- Common/cppcf/compoundfile.cpp | 297 ++++++++++++++++---------------- Common/cppcf/compoundfile.h | 28 +-- Common/cppcf/directoryentry.cpp | 16 +- Common/cppcf/header.cpp | 6 +- Common/cppcf/streamview.cpp | 6 +- 13 files changed, 284 insertions(+), 284 deletions(-) diff --git a/Common/cppcf/RBTree/rbtree.cpp b/Common/cppcf/RBTree/rbtree.cpp index 8df7084539..c3e0047f20 100644 --- a/Common/cppcf/RBTree/rbtree.cpp +++ b/Common/cppcf/RBTree/rbtree.cpp @@ -49,7 +49,7 @@ void RBTree::Insert(PIRBNode newNode) int compResult = newNode->CompareTo(n); if (compResult == 0) { - throw new RBTreeDuplicatedItemException(L"RBNode " + newNode->ToString() + L" already present in tree"); + throw RBTreeDuplicatedItemException(L"RBNode " + newNode->ToString() + L" already present in tree"); //n->Value = value; //return; } diff --git a/Common/cppcf/RBTree/rbtree.h b/Common/cppcf/RBTree/rbtree.h index 520c1c1990..7c8fb93f01 100644 --- a/Common/cppcf/RBTree/rbtree.h +++ b/Common/cppcf/RBTree/rbtree.h @@ -53,7 +53,7 @@ private: public: // todo this from C# and it's weak realization - class iterator : public std::iterator + class iterator : public std::iterator { std::list heap; std::list::iterator current; @@ -61,14 +61,14 @@ public: iterator(RBTree &tree, bool end = false); inline iterator& operator++() {++current; return *this;} inline iterator& operator--() {--current; return *this;} - inline bool operator==(iterator other) const {return current == other.current;} - inline bool operator!=(iterator other) const {return current != other.current;} + inline bool operator==(const iterator &other) const {return current == other.current;} + inline bool operator!=(const iterator &other) const {return current != other.current;} inline PIRBNode operator*() {return current->lock();} - inline void end() {current = heap.end();} + inline iterator end() {current = heap.end(); return *this;} }; - iterator begin() {return iterator(*this);} - iterator end()const; + iterator&& begin() {return std::move(iterator(*this));} + iterator&& end() {return std::move(iterator(*this).end());} private: PIRBNode root; diff --git a/Common/cppcf/cfitem.cpp b/Common/cppcf/cfitem.cpp index c134825fad..2ba799d71c 100644 --- a/Common/cppcf/cfitem.cpp +++ b/Common/cppcf/cfitem.cpp @@ -1,4 +1,6 @@ #include "cfitem.h" +#include "idirectoryentry.h" +#include "compoundfile.h" #include "cfexception.h" using namespace CFCPP; @@ -6,7 +8,7 @@ using namespace CFCPP; int CFItem::CompareTo(const CFItem &other) const { - return dirEntry->CompareTo(other.dirEntry); + return dirEntry.lock()->CompareTo(std::dynamic_pointer_cast(other.dirEntry.lock())); } bool CFItem::operator==(const CFItem &rightItem) const @@ -21,12 +23,12 @@ bool CFItem::operator!=(const CFItem &rightItem) const int CFItem::GetHashCode() const { - return dirEntry->GetHashCode(); + return dirEntry.lock()->GetHashCode(); } std::wstring CFItem::Name() const { - auto n = dirEntry->GetEntryName(); + auto n = dirEntry.lock()->GetEntryName(); if (n.empty() == false) { auto remIter = n.find_last_of('\0'); @@ -38,57 +40,62 @@ std::wstring CFItem::Name() const return L""; } +std::streamsize CFItem::size() const +{ + return dirEntry.lock()->getSize(); +} + bool CFItem::IsStorage() const { - return dirEntry->getStgType() == StgType::StgStorage; + return dirEntry.lock()->getStgType() == StgType::StgStorage; } bool CFItem::IsStream() const { - return dirEntry->getStgType() == StgType::StgStream; + return dirEntry.lock()->getStgType() == StgType::StgStream; } bool CFItem::ISRoot() const { - return dirEntry->getStgType() == StgType::StgRoot; + return dirEntry.lock()->getStgType() == StgType::StgRoot; } GUID CFItem::getStorageCLSID() const { - return dirEntry->getStorageCLSID(); + return dirEntry.lock()->getStorageCLSID(); } void CFItem::setStorageCLSID(GUID value) { - dirEntry->setStorageCLSID(value); -} - -int CFItem::CompareTo(const CFItem &other) -{ - return dirEntry->CompareTo(other.dirEntry); + dirEntry.lock()->setStorageCLSID(value); } std::wstring CFItem::ToString() const { - if (dirEntry != nullptr) - return L"[" + std::to_wstring(dirEntry->getLeftSibling()) + L"," + std::to_wstring(dirEntry->getSid()) + L"," + - std::to_wstring(dirEntry->getRightSibling()) + L"] " + dirEntry->GetEntryName(); + if (!dirEntry.expired()) + return L"[" + std::to_wstring(dirEntry.lock()->getLeftSibling()) + L"," + std::to_wstring(dirEntry.lock()->getSid()) + L"," + + std::to_wstring(dirEntry.lock()->getRightSibling()) + L"] " + dirEntry.lock()->GetEntryName(); else return L""; } -void CFItem::setDirEntry(const std::shared_ptr &newDirEntry) +void CFItem::setDirEntry(const std::weak_ptr &newDirEntry) { - if (newDirEntry == nullptr || newDirEntry->getSid() < 0) - throw new CFException("Attempting to create a CFStorage using an unitialized directory"); + if (newDirEntry.expired() || newDirEntry.lock()->getSid() < 0) + throw CFException("Attempting to create a CFStorage using an unitialized directory"); dirEntry = newDirEntry; } +std::shared_ptr CFItem::getDirEntry() const +{ + return dirEntry.lock(); +} + void CFItem::CheckDisposed() const { - if (compoundFile.lock()->IsClosed()) - throw new CFDisposedException("Owner Compound file has been closed and owned items have been invalidated"); + if (compoundFile != nullptr && compoundFile->IsClosed()) + throw CFDisposedException("Owner Compound file has been closed and owned items have been invalidated"); } diff --git a/Common/cppcf/cfitem.h b/Common/cppcf/cfitem.h index b510d30cbf..e2fa1acd12 100644 --- a/Common/cppcf/cfitem.h +++ b/Common/cppcf/cfitem.h @@ -1,24 +1,28 @@ #pragma once -#include "compoundfile.h" #include "guid.h" +#include +#include namespace CFCPP { +class CompoundFile; +class IDirectoryEntry; + struct DataTime { // TODO char data[8] = {0,0,0,0,0,0,0,0}; }; -class CFItem +class CFItem : protected std::enable_shared_from_this { public: int CompareTo(const CFItem& other) const; bool operator==(const CFItem &rightItem) const; bool operator!=(const CFItem &rightItem) const; int GetHashCode() const; - std::wstring Name()const; - virtual inline std::streamsize size() const {return dirEntry->getSize();} + std::wstring Name() const; + std::streamsize size() const; bool IsStorage() const; bool IsStream() const; bool ISRoot() const; @@ -30,23 +34,20 @@ public: void setStorageCLSID(GUID value); int CompareTo(const CFItem& other); - std::wstring ToString()const; + std::wstring ToString() const; - virtual void setDirEntry(const std::shared_ptr &newDirEntry); + void setDirEntry(const std::weak_ptr &newDirEntry); + std::shared_ptr getDirEntry() const; friend class CompoundFile; - std::weak_ptr compoundFile; protected: - std::shared_ptr dirEntry; + std::weak_ptr dirEntry; + CompoundFile* compoundFile; protected: CFItem() {}; - CFItem(std::weak_ptr compoundFile) : compoundFile(compoundFile) {} - inline std::shared_ptr getCompoundFile() {return compoundFile.lock();} + CFItem(CompoundFile* compoundFile) : compoundFile(compoundFile) {} + inline CompoundFile* getCompoundFile() {return compoundFile;} void CheckDisposed() const; }; - -using PCFItem = std::shared_ptr; - - } diff --git a/Common/cppcf/cfstorage.cpp b/Common/cppcf/cfstorage.cpp index a3540ac5ac..4355c75f45 100644 --- a/Common/cppcf/cfstorage.cpp +++ b/Common/cppcf/cfstorage.cpp @@ -1,5 +1,7 @@ #include "cfstorage.h" #include "cfexception.h" +#include "compoundfile.h" +#include "directoryentry.h" #include "RBTree/rbtreeexception.h" #include "RBTree/irbnode.h" @@ -7,7 +9,7 @@ using namespace CFCPP; using RedBlackTree::RBTree; -CFStorage::CFStorage(const std::weak_ptr &compFile, const std::shared_ptr &dirEntry) : +CFStorage::CFStorage(CompoundFile *compFile, const std::weak_ptr &dirEntry) : CFItem(compFile) { setDirEntry(dirEntry); @@ -17,11 +19,8 @@ std::shared_ptr CFStorage::getChildren() { if (children == nullptr) { - //if (this.CompoundFile.HasSourceStream) - //{ - children = LoadChildren(this->dirEntry->getSid()); - //} - //else + children = LoadChildren(this->dirEntry.lock()->getSid()); + if (children == nullptr) { children = CompoundFile::CreateNewTree(); @@ -39,10 +38,7 @@ std::shared_ptr CFStorage::AddStream(const std::wstring& streamName) - std::shared_ptr dirEntry = DirectoryEntry::TryNew(streamName, StgType::StgStream, compoundFile.lock()->GetDirectories().cast()); - - // Add new Stream directory entry - //cfo = new CFStream(this.CompoundFile, streamName); + std::shared_ptr dirEntry = DirectoryEntry::TryNew(streamName, StgType::StgStream, compoundFile->GetDirectories().cast()); try { @@ -54,15 +50,12 @@ std::shared_ptr CFStorage::AddStream(const std::wstring& streamName) } catch (RedBlackTree::RBTreeException &rbex) { - compoundFile.lock()->ResetDirectoryEntry(dirEntry->getSid()); + compoundFile->ResetDirectoryEntry(dirEntry->getSid()); - throw new CFDuplicatedItemException(L"An entry with name '" + streamName + L"' is already present in storage '" + Name() + L"' "); + throw CFDuplicatedItemException(L"An entry with name '" + streamName + L"' is already present in storage '" + Name() + L"' "); } - auto pstream = std::shared_ptr(new CFStream); - std::static_pointer_cast(pstream)->compoundFile = compoundFile; - std::static_pointer_cast(pstream)->setDirEntry(dirEntry); - return pstream; + return std::shared_ptr(new CFStream(compoundFile, dirEntry)); } std::shared_ptr CFStorage::GetStream(const std::wstring& streamName) @@ -76,10 +69,7 @@ std::shared_ptr CFStorage::GetStream(const std::wstring& streamName) if (children->TryLookup(tmp, outDe) && ((std::static_pointer_cast(outDe))->getStgType() == StgType::StgStream)) { - auto pstream = std::shared_ptr(new CFStream); - std::static_pointer_cast(pstream)->compoundFile = compoundFile; - std::static_pointer_cast(pstream)->setDirEntry(std::static_pointer_cast(outDe)); - return pstream; + return std::shared_ptr(new CFStream(compoundFile, std::static_pointer_cast(outDe))); } else { @@ -103,10 +93,7 @@ bool CFStorage::TryGetStream(const std::wstring& streamName, std::shared_ptrTryLookup(tmp, outDe) && ((std::static_pointer_cast(outDe))->getStgType() == StgType::StgStream)) { - auto pstream = std::shared_ptr(new CFStream); - std::static_pointer_cast(pstream)->compoundFile = compoundFile; - std::static_pointer_cast(pstream)->setDirEntry(std::static_pointer_cast(outDe)); - cfStream = pstream; + cfStream = std::shared_ptr(new CFStream(compoundFile, std::static_pointer_cast(outDe))); result = true; } } @@ -184,11 +171,11 @@ std::shared_ptr CFStorage::AddStorage(const std::wstring &storageName CheckDisposed(); if (storageName.empty()) - throw new CFException("Stream name cannot be null or empty"); + throw CFException("Stream name cannot be null or empty"); // Add new Storage directory entry std::shared_ptr cfo - = DirectoryEntry::New(storageName, StgType::StgStorage, compoundFile.lock()->GetDirectories().cast()); + = DirectoryEntry::New(storageName, StgType::StgStorage, compoundFile->GetDirectories().cast()); //this.CompoundFile.InsertNewDirectoryEntry(cfo); @@ -199,18 +186,18 @@ std::shared_ptr CFStorage::AddStorage(const std::wstring &storageName } catch (RedBlackTree::RBTreeDuplicatedItemException& ex) { - compoundFile.lock()->ResetDirectoryEntry(cfo->getSid()); + compoundFile->ResetDirectoryEntry(cfo->getSid()); cfo.reset(); - throw new CFDuplicatedItemException(L"An entry with name '" + storageName + L"' is already present in storage '" + Name() + L"' "); + throw CFDuplicatedItemException(L"An entry with name '" + storageName + L"' is already present in storage '" + Name() + L"' "); } std::shared_ptr childrenRoot = std::dynamic_pointer_cast(children->getRoot()); - dirEntry->setChild(childrenRoot->getSid()); + dirEntry.lock()->setChild(childrenRoot->getSid()); return std::shared_ptr(new CFStorage(compoundFile, cfo)); } -void CFStorage::VisitEntries(RedBlackTree::Action action, bool recursive) +void CFStorage::VisitEntries(RedBlackTree::Action > action, bool recursive) { CheckDisposed(); @@ -224,13 +211,14 @@ void CFStorage::VisitEntries(RedBlackTree::Action action, bool recursiv auto d = std::dynamic_pointer_cast(targetNode); if (d->getStgType() == StgType::StgStream) { - std::shared_ptr pstream (new CFStream); - std::static_pointer_cast(pstream)->compoundFile = compoundFile; - std::static_pointer_cast(pstream)->setDirEntry(d); + std::shared_ptr pstream (new CFStream(compoundFile, d)); action(std::static_pointer_cast(pstream)); } else - action(PCFItem(new CFStorage(compoundFile, d))); + { + std::shared_ptr pstorage(new CFStorage(compoundFile, d)); + action(std::static_pointer_cast(pstorage)); + } if (d->getChild() != DirectoryEntry::NOSTREAM) subStorages.push_back(targetNode); @@ -259,10 +247,10 @@ void CFStorage::Delete(const std::wstring &entryName) children->TryLookup(tmp, foundObj); if (foundObj == nullptr) - throw new CFItemNotFound(L"Entry named [" + entryName + L"] was not found"); + throw CFItemNotFound(L"Entry named [" + entryName + L"] was not found"); if (std::dynamic_pointer_cast(foundObj)->getStgType() == StgType::StgRoot) - throw new CFException("Root storage cannot be removed"); + throw CFException("Root storage cannot be removed"); RedBlackTree::PIRBNode altDel; @@ -281,9 +269,9 @@ void CFStorage::Delete(const std::wstring &entryName) // ...then we need to rethread the root of siblings tree... if (children->getRoot() != nullptr) - dirEntry->setChild(std::dynamic_pointer_cast(children->getRoot())->getSid()); + dirEntry.lock()->setChild(std::dynamic_pointer_cast(children->getRoot())->getSid()); else - dirEntry->setChild(DirectoryEntry::NOSTREAM); + dirEntry.lock()->setChild(DirectoryEntry::NOSTREAM); // ...and finally Remove storage item from children tree... children->Delete(foundObj, altDel); @@ -295,7 +283,7 @@ void CFStorage::Delete(const std::wstring &entryName) foundObj = altDel; } - compoundFile.lock()->InvalidateDirectoryEntry(std::dynamic_pointer_cast(foundObj)->getSid()); + compoundFile->InvalidateDirectoryEntry(std::dynamic_pointer_cast(foundObj)->getSid()); break; } @@ -303,16 +291,16 @@ void CFStorage::Delete(const std::wstring &entryName) case StgType::StgStream: { // Free directory associated data stream. - compoundFile.lock()->FreeAssociatedData(std::dynamic_pointer_cast(foundObj)->getSid()); + compoundFile->FreeAssociatedData(std::dynamic_pointer_cast(foundObj)->getSid()); // Remove item from children tree children->Delete(foundObj, altDel); // Rethread the root of siblings tree... if (children->getRoot() != nullptr) - dirEntry->setChild(std::dynamic_pointer_cast(children->getRoot())->getSid()); + dirEntry.lock()->setChild(std::dynamic_pointer_cast(children->getRoot())->getSid()); else - dirEntry->setChild(DirectoryEntry::NOSTREAM); + dirEntry.lock()->setChild(DirectoryEntry::NOSTREAM); // Delete operation could possibly have cloned a directory, changing its SID. // Invalidate the ACTUALLY deleted directory. @@ -321,7 +309,7 @@ void CFStorage::Delete(const std::wstring &entryName) foundObj = altDel; } - compoundFile.lock()->InvalidateDirectoryEntry(std::dynamic_pointer_cast(foundObj)->getSid()); + compoundFile->InvalidateDirectoryEntry(std::dynamic_pointer_cast(foundObj)->getSid()); } default: break; @@ -337,25 +325,25 @@ void CFStorage::RenameItem(const std::wstring &oldItemName, const std::wstring & { std::dynamic_pointer_cast(item)->SetEntryName(newItemName); } - else throw new CFItemNotFound(L"Item " + oldItemName + L" not found in Storage"); + else throw CFItemNotFound(L"Item " + oldItemName + L" not found in Storage"); children.reset(); - children = LoadChildren(dirEntry->getSid()); //Rethread + children = LoadChildren(dirEntry.lock()->getSid()); //Rethread if (children == nullptr) { - children = compoundFile.lock()->CreateNewTree(); + children = compoundFile->CreateNewTree(); } } std::shared_ptr CFStorage::LoadChildren(int SID) { - std::shared_ptr childrenTree = compoundFile.lock()->GetChildrenTree(SID); + std::shared_ptr childrenTree = compoundFile->GetChildrenTree(SID); if (childrenTree->getRoot() != nullptr) - dirEntry->setChild((std::static_pointer_cast(childrenTree->getRoot())->getSid())); + dirEntry.lock()->setChild((std::static_pointer_cast(childrenTree->getRoot())->getSid())); else - dirEntry->setChild(DirectoryEntry::NOSTREAM); + dirEntry.lock()->setChild(DirectoryEntry::NOSTREAM); return childrenTree; } diff --git a/Common/cppcf/cfstorage.h b/Common/cppcf/cfstorage.h index b9760eadc7..f20d7d1491 100644 --- a/Common/cppcf/cfstorage.h +++ b/Common/cppcf/cfstorage.h @@ -1,8 +1,6 @@ #pragma once -#include "cfitem.h" #include "RBTree/rbtree.h" -#include "compoundfile.h" #include "idirectoryentry.h" #include "cfstream.h" @@ -12,7 +10,7 @@ namespace CFCPP class CFStorage : public CFItem { public: - CFStorage(const std::weak_ptr &compFile, const std::shared_ptr &dirEntry); + CFStorage(CompoundFile* compFile, const std::weak_ptr &dirEntry); std::shared_ptr getChildren(); @@ -24,11 +22,10 @@ public: std::shared_ptr TryGetStorage(const std::wstring& storageName); bool TryGetStorage(const std::wstring& storageName, std::shared_ptr &cfStorage); std::shared_ptr AddStorage(const std::wstring& storageName); - void VisitEntries(RedBlackTree::Action action, bool recursive); + void VisitEntries(RedBlackTree::Action> action, bool recursive); void Delete(const std::wstring& entryName); void RenameItem(const std::wstring& oldItemName, const std::wstring& newItemName); std::streamsize size() const {return CFItem::size();} - std::shared_ptr getDirEntry() const {return dirEntry;} private: std::shared_ptr LoadChildren(int SID); diff --git a/Common/cppcf/cfstream.cpp b/Common/cppcf/cfstream.cpp index 75978edc91..e12a5aa13b 100644 --- a/Common/cppcf/cfstream.cpp +++ b/Common/cppcf/cfstream.cpp @@ -1,13 +1,15 @@ #include "cfstream.h" #include "cfexception.h" +#include "idirectoryentry.h" +#include "compoundfile.h" using namespace CFCPP; -CFStream::CFStream(std::weak_ptr compFile, std::shared_ptr dirEntry) : +CFStream::CFStream(CompoundFile* compFile, std::weak_ptr dirEntry) : CFItem(compFile) { - if (dirEntry == nullptr || dirEntry->getSid() < 0) - throw new CFException("Attempting to create a CFStorage using an unitialized directory"); + if (dirEntry.expired() || dirEntry.lock()->getSid() < 0) + throw CFException("Attempting to create a CFStorage using an unitialized directory"); this->dirEntry = dirEntry; } @@ -16,8 +18,8 @@ void CFStream::SetData(const std::vector &data) { CheckDisposed(); - compoundFile.lock()->FreeData(this); - compoundFile.lock()->WriteData(this, data); + compoundFile->FreeData(this); + compoundFile->WriteData(shared_from_this(), data); } void CFStream::Write(const std::vector &data, std::streamsize position) @@ -28,7 +30,7 @@ void CFStream::Write(const std::vector &data, std::streamsize position) void CFStream::Write(const std::vector &data, std::streamsize position, int offset, int count) { CheckDisposed(); - compoundFile.lock()->WriteData(this, data, position, offset, count); + compoundFile->WriteData(shared_from_this(), data, position, offset, count); } void CFStream::Append(const std::vector &data) @@ -36,11 +38,11 @@ void CFStream::Append(const std::vector &data) CheckDisposed(); if (size() > 0) { - compoundFile.lock()->AppendData(this, data); + compoundFile->AppendData(shared_from_this(), data); } else { - compoundFile.lock()->WriteData(this, data); + compoundFile->WriteData(shared_from_this(), data); } } @@ -48,19 +50,19 @@ std::vector CFStream::getData() const { CheckDisposed(); - return compoundFile.lock()->GetData(this); + return compoundFile->GetData(this); } int CFStream::Read(std::vector &buffer, std::streamsize position, int count) { CheckDisposed(); - return compoundFile.lock()->ReadData(this, position, buffer, 0, count); + return compoundFile->ReadData(this, position, buffer, 0, count); } int CFStream::Read(std::vector &buffer, std::streamsize position, int offset, int count) { CheckDisposed(); - return compoundFile.lock()->ReadData(this, position, buffer, offset, count); + return compoundFile->ReadData(this, position, buffer, offset, count); } void CFStream::CopyFrom(const Stream &input) @@ -80,5 +82,5 @@ void CFStream::CopyFrom(const Stream &input) void CFStream::Resize(std::streamsize length) { - compoundFile.lock()->SetStreamLength(this, length); + compoundFile->SetStreamLength(shared_from_this(), length); } diff --git a/Common/cppcf/cfstream.h b/Common/cppcf/cfstream.h index 0dd73d061f..c9882768f6 100644 --- a/Common/cppcf/cfstream.h +++ b/Common/cppcf/cfstream.h @@ -1,13 +1,15 @@ #pragma once +#include "Stream.h" #include "cfitem.h" +#include namespace CFCPP { class CFStream : public CFItem { public: - CFStream(std::weak_ptr compFile, std::shared_ptr dirEntry); + CFStream(CompoundFile* compFile, std::weak_ptr dirEntry); void SetData(const std::vector& data); void Write(const std::vector& data, std::streamsize position); diff --git a/Common/cppcf/compoundfile.cpp b/Common/cppcf/compoundfile.cpp index 758b6ed06a..b2e18ac8e6 100644 --- a/Common/cppcf/compoundfile.cpp +++ b/Common/cppcf/compoundfile.cpp @@ -1,9 +1,12 @@ #include "compoundfile.h" +#include "cfstorage.h" +#include "header.h" +#include "directoryentry.h" #include "cfexception.h" #include "streamview.h" #include "../../DesktopEditor/common/File.h" -#include #include +#include using namespace CFCPP; @@ -26,12 +29,12 @@ CompoundFile::CompoundFile(const std::wstring &fileName, CFSUpdateMode updateMod FAT_SECTOR_ENTRIES_COUNT = (GetSectorSize() / 4); } -CompoundFile::CompoundFile(CFSVersion cfsVersion, CFSConfiguration configFlags) : header((ushort)cfsVersion) +CompoundFile::CompoundFile(CFSVersion cfsVersion, CFSConfiguration configFlags) : header(new Header(cfsVersion)) { configuration = configFlags; sectorRecycle = configFlags & CFSConfiguration::SectorRecycle; - bool eraseFreeSectors = configFlags & CFSConfiguration::EraseFreeSectors; + eraseFreeSectors = configFlags & CFSConfiguration::EraseFreeSectors; if (cfsVersion == CFSVersion::Ver_4) { @@ -48,10 +51,7 @@ CompoundFile::CompoundFile(CFSVersion cfsVersion, CFSConfiguration configFlags) rootDir->setStgColor(StgColor::Black); //InsertNewDirectoryEntry(rootDir); - auto pstorage = std::shared_ptr(new CFStorage); - pstorage->compoundFile = shared_from_this(); - std::static_pointer_cast(pstorage)->setDirEntry(rootDir); - rootStorage = pstorage; + rootStorage.reset(new CFStorage(this, rootDir)); } CompoundFile::CompoundFile(const std::wstring &fileName) @@ -77,26 +77,26 @@ CompoundFile::CompoundFile(Stream stream) void CompoundFile::OnSizeLimitReached() { std::shared_ptr rangeLockSector(new Sector(GetSectorSize(), sourceStream)); + sectors.Add(rangeLockSector); rangeLockSector->type = SectorType::RangeLockSector; _transactionLockAdded = true; _lockSectorId = rangeLockSector->id; - sectors.Add(rangeLockSector); } void CompoundFile::Commit(bool releaseMemory) { if (_disposed) - throw new CFDisposedException("Compound File closed: cannot commit data"); + throw CFDisposedException("Compound File closed: cannot commit data"); if (updateMode != CFSUpdateMode::Update) - throw new CFInvalidOperation("Cannot commit data in Read-Only update mode"); + throw CFInvalidOperation("Cannot commit data in Read-Only update mode"); int sSize = GetSectorSize(); - if (header.majorVersion != (ushort)CFSVersion::Ver_3) + if (header->majorVersion != (ushort)CFSVersion::Ver_3) CheckForLockSector(); sourceStream->seekp(0, std::ios::beg); @@ -146,18 +146,18 @@ void CompoundFile::Commit(bool releaseMemory) // Seek to beginning position and save header (first 512 or 4096 bytes) sourceStream->seekg(0, std::ios::beg); - header.Write(sourceStream); + header->Write(sourceStream); // sourceStream-> SetLength((long)(sectors.Count + 1) * sSize); sourceStream->flush(); - if (releaseMemory) - GC.Collect(); +// if (releaseMemory) +// GC.Collect(); //} //catch (Exception ex) //{ - // throw new CFException("Internal error while committing data", ex); + // throw CFException("Internal error while committing data", ex); //} } @@ -193,12 +193,12 @@ void CompoundFile::Load(Stream stream) { try { - this->header = Header(); + header.reset(new Header); directoryEntries.clear(); this->sourceStream = stream; - header.Read(stream); + header->Read(stream); int n_sector = std::ceil(((double)(Length(stream) - GetSectorSize()) / (double)GetSectorSize())); @@ -215,11 +215,7 @@ void CompoundFile::Load(Stream stream) LoadDirectories(); - - auto pstorage = std::shared_ptr(new CFStorage); - pstorage->compoundFile = shared_from_this(); - std::static_pointer_cast(pstorage)->setDirEntry(directoryEntries[0]); - rootStorage = pstorage; + rootStorage.reset(new CFStorage(this, directoryEntries[0])); } catch (...) { @@ -235,7 +231,7 @@ void CompoundFile::Load(Stream stream) void CompoundFile::Save(std::wstring wFileName) { if (_disposed) - throw new CFException("Compound File closed: cannot save data"); + throw CFException("Compound File closed: cannot save data"); BYTE* pUtf8 = NULL; LONG lLen = 0; @@ -250,7 +246,7 @@ void CompoundFile::Save(std::wstring wFileName) } catch (std::exception& ex) { - throw new CFException("Error saving file [" + fileName + "]", ex); + throw CFException("Error saving file [" + fileName + "]", ex); } // finally { @@ -266,10 +262,10 @@ void CompoundFile::Save(std::wstring wFileName) void CompoundFile::Save(Stream stream) { if (_disposed) - throw new CFDisposedException("Compound File closed: cannot save data"); + throw CFDisposedException("Compound File closed: cannot save data"); // if (!stream.CanSeek) - // throw new CFException("Cannot save on a non-seekable stream"); + // throw CFException("Cannot save on a non-seekable stream"); CheckForLockSector(); int sSize = GetSectorSize(); @@ -307,11 +303,11 @@ void CompoundFile::Save(Stream stream) } stream->seekp(0, std::ios::beg); - header.Write(stream); + header->Write(stream); } catch (std::exception &ex) { - throw new CFException("Internal error while saving compound file to stream ", ex); + throw CFException("Internal error while saving compound file to stream ", ex); } } @@ -328,9 +324,9 @@ SVector CompoundFile::GetFatSectorChain() int idx = 0; // Read FAT entries from the header Fat entry array (max 109 entries) - while (idx < header.fatSectorsNumber && idx < N_HEADER_FAT_ENTRY) + while (idx < header->fatSectorsNumber && idx < N_HEADER_FAT_ENTRY) { - nextSecID = header.difat[idx]; + nextSecID = header->difat[idx]; auto s = sectors[nextSecID]; if (s.get() == nullptr) @@ -350,8 +346,8 @@ SVector CompoundFile::GetFatSectorChain() if (difatSectors.size() > 0) { std::unordered_set processedSectors; - std::streamsize stLength = header.fatSectorsNumber > N_HEADER_FAT_ENTRY ? - (header.fatSectorsNumber - N_HEADER_FAT_ENTRY) * 4 : 0; + std::streamsize stLength = header->fatSectorsNumber > N_HEADER_FAT_ENTRY ? + (header->fatSectorsNumber - N_HEADER_FAT_ENTRY) * 4 : 0; SList zeroQueue; std::shared_ptr difatStream( @@ -369,7 +365,7 @@ SVector CompoundFile::GetFatSectorChain() int i = 0; - while ((int)result.size() < header.fatSectorsNumber) + while ((int)result.size() < header->fatSectorsNumber) { difatStream->Read(nextDIFATSectorBuffer, 0, 4); // IsLittleEndian ? nextSecID = *reinterpret_cast(nextDIFATSectorBuffer); @@ -420,18 +416,18 @@ SVector CompoundFile::GetDifatSectorChain() std::unordered_set processedSectors; - if (header.difatSectorsNumber != 0) + if (header->difatSectorsNumber != 0) { - validationCount = (int)header.difatSectorsNumber; + validationCount = (int)header->difatSectorsNumber; - std::shared_ptr s = sectors[header.firstDIFATSectorID]; + std::shared_ptr s = sectors[header->firstDIFATSectorID]; if (s == nullptr) //Lazy loading { s.reset(new Sector(GetSectorSize(), sourceStream)); s->type = SectorType::DIFAT; - s->id = header.firstDIFATSectorID; - sectors[header.firstDIFATSectorID] = s; + s->id = header->firstDIFATSectorID; + sectors[header->firstDIFATSectorID] = s; } result.push_back(s); @@ -456,7 +452,7 @@ SVector CompoundFile::GetDifatSectorChain() this->Close(); if (this->validationExceptionEnabled) - throw new CFCorruptedFileException("DIFAT sectors count mismatched. Corrupted compound file"); + throw CFCorruptedFileException("DIFAT sectors count mismatched. Corrupted compound file"); } s = sectors[nextSecID]; @@ -492,10 +488,10 @@ SVector CompoundFile::GetNormalSectorChain(int secID) if (nextSecID == Sector::ENDOFCHAIN) break; if (nextSecID < 0) - throw new CFCorruptedFileException("Next Sector ID reference is below zero. NextID : " + std::to_string(nextSecID)); + throw CFCorruptedFileException("Next Sector ID reference is below zero. NextID : " + std::to_string(nextSecID)); if (nextSecID >= sectors.Count()) - throw new CFCorruptedFileException("Next Sector ID reference an out of range sector. NextID : " + std::to_string(nextSecID) + + throw CFCorruptedFileException("Next Sector ID reference an out of range sector. NextID : " + std::to_string(nextSecID) + " while sector count " + std::to_string(sectors.Count())); std::shared_ptr s = sectors[nextSecID]; @@ -530,11 +526,11 @@ SVector CompoundFile::GetMiniSectorChain(int secID) { int nextSecID = secID; - SVector miniFAT = GetNormalSectorChain(header.firstMiniFATSectorID); + SVector miniFAT = GetNormalSectorChain(header->firstMiniFATSectorID); SVector miniStream = GetNormalSectorChain(RootEntry()->getStartSetc()); SList zeroQueue; - StreamView miniFATView(miniFAT, GetSectorSize(), header.miniFATSectorsNumber * Sector::MINISECTOR_SIZE, zeroQueue, sourceStream); + StreamView miniFATView(miniFAT, GetSectorSize(), header->miniFATSectorsNumber * Sector::MINISECTOR_SIZE, zeroQueue, sourceStream); StreamView miniStreamView(miniStream, GetSectorSize(), rootStorage->size(), zeroQueue, sourceStream); @@ -584,7 +580,7 @@ SVector CompoundFile::GetSectorChain(int secID, SectorType chainType) return GetMiniSectorChain(secID); default: - throw new CFException("Unsupproted chain type"); + throw CFException("Unsupproted chain type"); } } @@ -592,7 +588,7 @@ void CompoundFile::EnsureUniqueSectorIndex(int nextSecID, std::unordered_setvalidationExceptionEnabled) { - throw new CFCorruptedFileException("The file is corrupted."); + throw CFCorruptedFileException("The file is corrupted."); } processedSectors.insert(nextSecID); @@ -603,7 +599,7 @@ void CompoundFile::CommitDirectory() const int DIRECTORY_SIZE = 128; auto directorySectors - = GetSectorChain(header.firstDirectorySectorID, SectorType::Normal); + = GetSectorChain(header->firstDirectorySectorID, SectorType::Normal); SList zeroQueue; std::shared_ptr sv( @@ -638,16 +634,16 @@ void CompoundFile::CommitDirectory() AllocateSectorChain(directorySectors); - header.firstDirectorySectorID = directorySectors[0]->id; + header->firstDirectorySectorID = directorySectors[0]->id; //Version 4 supports directory sectors count - if (header.majorVersion == 3) + if (header->majorVersion == 3) { - header.directorySectorsNumber = 0; + header->directorySectorsNumber = 0; } else { - header.directorySectorsNumber = directorySectors.size(); + header->directorySectorsNumber = directorySectors.size(); } } @@ -759,7 +755,7 @@ bool CompoundFile::ValidateSibling(int sid) if (this->validationExceptionEnabled) { //Close(); - throw new CFCorruptedFileException("A Directory Entry references the non-existent sid number " + std::to_string(sid)); + throw CFCorruptedFileException("A Directory Entry references the non-existent sid number " + std::to_string(sid)); } else return false; @@ -771,7 +767,7 @@ bool CompoundFile::ValidateSibling(int sid) if (this->validationExceptionEnabled) { //Close(); - throw new CFCorruptedFileException("A Directory Entry has a valid reference to an Invalid Storage Type directory [" + std::to_string(sid) + "]"); + throw CFCorruptedFileException("A Directory Entry has a valid reference to an Invalid Storage Type directory [" + std::to_string(sid) + "]"); } else return false; @@ -784,14 +780,14 @@ bool CompoundFile::ValidateSibling(int sid) if (this->validationExceptionEnabled) { //Close(); - throw new CFCorruptedFileException("A Directory Entry has an invalid Storage Type"); + throw CFCorruptedFileException("A Directory Entry has an invalid Storage Type"); } else return false; } if (std::find(levelSIDs.begin(), levelSIDs.end(), sid) != levelSIDs.end()) - throw new CFCorruptedFileException("Cyclic reference of directory item"); + throw CFCorruptedFileException("Cyclic reference of directory item"); return true; //No fault condition encountered for sid being validated } @@ -802,13 +798,13 @@ bool CompoundFile::ValidateSibling(int sid) void CompoundFile::LoadDirectories() { SVector directoryChain - = GetSectorChain(header.firstDirectorySectorID, SectorType::Normal); + = GetSectorChain(header->firstDirectorySectorID, SectorType::Normal); if (!(directoryChain.size() > 0)) - throw new CFCorruptedFileException("Directory sector chain MUST contain at least 1 sector"); + throw CFCorruptedFileException("Directory sector chain MUST contain at least 1 sector"); - if (header.firstDirectorySectorID == Sector::ENDOFCHAIN) - header.firstDirectorySectorID = directoryChain[0]->id; + if (header->firstDirectorySectorID == Sector::ENDOFCHAIN) + header->firstDirectorySectorID = directoryChain[0]->id; SList zeroQueue; StreamView dirReader(directoryChain, GetSectorSize(), directoryChain.size() * GetSectorSize(), zeroQueue, sourceStream); @@ -835,13 +831,13 @@ void CompoundFile::FreeMiniChain(SVector §orChain, int nth_sector_to std::vector ZEROED_MINI_SECTOR(Sector::MINISECTOR_SIZE); SVector miniFAT - = GetSectorChain(header.firstMiniFATSectorID, SectorType::Normal); + = GetSectorChain(header->firstMiniFATSectorID, SectorType::Normal); SVector miniStream = GetSectorChain(RootEntry()->getStartSetc(), SectorType::Normal); SList zeroQueue; - StreamView miniFATView(miniFAT, GetSectorSize(), header.miniFATSectorsNumber * Sector::MINISECTOR_SIZE, zeroQueue, sourceStream); + StreamView miniFATView(miniFAT, GetSectorSize(), header->miniFATSectorsNumber * Sector::MINISECTOR_SIZE, zeroQueue, sourceStream); StreamView miniStreamView(miniStream, GetSectorSize(), rootStorage->size(), zeroQueue, sourceStream); @@ -889,8 +885,8 @@ void CompoundFile::FreeMiniChain(SVector §orChain, int nth_sector_to if (miniFAT.size() > 0) { rootStorage->getDirEntry()->setStartSetc(miniStream[0]->id); - header.miniFATSectorsNumber = miniFAT.size(); - header.firstMiniFATSectorID = miniFAT[0]->id; + header->miniFATSectorsNumber = miniFAT.size(); + header->firstMiniFATSectorID = miniFAT[0]->id; } } @@ -958,7 +954,7 @@ void CompoundFile::AllocateFATSectorChain(SVector §orChain) StreamView fatStream( fatSectors, GetSectorSize(), - header.fatSectorsNumber * GetSectorSize(), + header->fatSectorsNumber * GetSectorSize(), zeroQueue, sourceStream, true @@ -986,7 +982,7 @@ void CompoundFile::AllocateFATSectorChain(SVector §orChain) void CompoundFile::AllocateDIFATSectorChain(SVector &FATsectorChain) { // Get initial sector's count - header.fatSectorsNumber = FATsectorChain.size(); + header->fatSectorsNumber = FATsectorChain.size(); // Allocate Sectors for (auto s : FATsectorChain) @@ -1003,19 +999,19 @@ void CompoundFile::AllocateDIFATSectorChain(SVector &FATsectorChain) int nCurrentSectors = sectors.Count(); // Temp DIFAT count - int nDIFATSectors = (int)header.difatSectorsNumber; + int nDIFATSectors = (int)header->difatSectorsNumber; if ((int)FATsectorChain.size() > HEADER_DIFAT_ENTRIES_COUNT) { nDIFATSectors = std::ceil((double)(FATsectorChain.size() - HEADER_DIFAT_ENTRIES_COUNT) / DIFAT_SECTOR_FAT_ENTRIES_COUNT); - nDIFATSectors = LowSaturation(nDIFATSectors - (int)header.difatSectorsNumber); //required DIFAT + nDIFATSectors = LowSaturation(nDIFATSectors - (int)header->difatSectorsNumber); //required DIFAT } // ...sum with new required DIFAT sectors count nCurrentSectors += nDIFATSectors; // ReCheck FAT bias - while (header.fatSectorsNumber * FAT_SECTOR_ENTRIES_COUNT < nCurrentSectors) + while (header->fatSectorsNumber * FAT_SECTOR_ENTRIES_COUNT < nCurrentSectors) { std::shared_ptr extraFATSector (new Sector(GetSectorSize(), sourceStream)); sectors.Add(extraFATSector); @@ -1025,14 +1021,14 @@ void CompoundFile::AllocateDIFATSectorChain(SVector &FATsectorChain) FATsectorChain.push_back(extraFATSector); - header.fatSectorsNumber++; + header->fatSectorsNumber++; nCurrentSectors++; //... so, adding a FAT sector may induce DIFAT sectors to increase by one // and consequently this may induce ANOTHER FAT sector (TO-THINK: May this condition occure ?) if (nDIFATSectors * DIFAT_SECTOR_FAT_ENTRIES_COUNT < - (header.fatSectorsNumber > HEADER_DIFAT_ENTRIES_COUNT ? - header.fatSectorsNumber - HEADER_DIFAT_ENTRIES_COUNT : + (header->fatSectorsNumber > HEADER_DIFAT_ENTRIES_COUNT ? + header->fatSectorsNumber - HEADER_DIFAT_ENTRIES_COUNT : 0)) { nDIFATSectors++; @@ -1051,7 +1047,7 @@ void CompoundFile::AllocateDIFATSectorChain(SVector &FATsectorChain) { if (i < HEADER_DIFAT_ENTRIES_COUNT) { - header.difat[i] = FATsectorChain[i]->id; // int to byte + header->difat[i] = FATsectorChain[i]->id; // int to byte } else { @@ -1077,16 +1073,16 @@ void CompoundFile::AllocateDIFATSectorChain(SVector &FATsectorChain) } } - header.difatSectorsNumber = (uint)nDIFATSectors; + header->difatSectorsNumber = (uint)nDIFATSectors; // Chain first sector if (difatStream.BaseSectorChain().size() && difatStream.BaseSectorChain().size() > 0) { - header.firstDIFATSectorID = difatStream.BaseSectorChain()[0]->id; + header->firstDIFATSectorID = difatStream.BaseSectorChain()[0]->id; // Update header information - header.difatSectorsNumber = (uint)difatStream.BaseSectorChain().size(); + header->difatSectorsNumber = (uint)difatStream.BaseSectorChain().size(); // Write chaining information at the end of DIFAT Sectors for (int i = 0; i < (int)difatStream.BaseSectorChain().size() - 1; i++) @@ -1104,19 +1100,19 @@ void CompoundFile::AllocateDIFATSectorChain(SVector &FATsectorChain) std::copy(src, dst+offsetDst, sizeof(int)); } else - header.firstDIFATSectorID = Sector::ENDOFCHAIN; + header->firstDIFATSectorID = Sector::ENDOFCHAIN; // Mark DIFAT Sectors in FAT SList zeroQueue; - StreamView fatSv(FATsectorChain, GetSectorSize(), header.fatSectorsNumber * GetSectorSize(), zeroQueue, sourceStream); + StreamView fatSv(FATsectorChain, GetSectorSize(), header->fatSectorsNumber * GetSectorSize(), zeroQueue, sourceStream); - for (int i = 0; i < (int)header.difatSectorsNumber; i++) + for (int i = 0; i < (int)header->difatSectorsNumber; i++) { fatSv.Seek(difatStream.BaseSectorChain()[i]->id * 4, std::ios::beg); fatSv.Write(reinterpret_cast(&Sector::DIFSECT), 0, 4); } - for (int i = 0; i < header.fatSectorsNumber; i++) + for (int i = 0; i < header->fatSectorsNumber; i++) { fatSv.Seek(fatSv.BaseSectorChain()[i]->id * 4, std::ios::beg); fatSv.Write(reinterpret_cast(&Sector::FATSECT), 0, 4); @@ -1125,13 +1121,13 @@ void CompoundFile::AllocateDIFATSectorChain(SVector &FATsectorChain) //fatSv.Seek(fatSv.BaseSectorChain[fatSv.BaseSectorChain.Count - 1].Id * 4, SeekOrigin.Begin); //fatSv.Write(BitConverter.GetBytes(Sector.ENDOFCHAIN), 0, 4); - header.fatSectorsNumber = fatSv.BaseSectorChain().size(); + header->fatSectorsNumber = fatSv.BaseSectorChain().size(); } void CompoundFile::AllocateMiniSectorChain(SVector §orChain) { SVector miniFAT - = GetSectorChain(header.firstMiniFATSectorID, SectorType::Normal); + = GetSectorChain(header->firstMiniFATSectorID, SectorType::Normal); SVector miniStream = GetSectorChain(RootEntry()->getStartSetc(), SectorType::Normal); @@ -1140,7 +1136,7 @@ void CompoundFile::AllocateMiniSectorChain(SVector §orChain) StreamView miniFATView( miniFAT, GetSectorSize(), - header.miniFATSectorsNumber * Sector::MINISECTOR_SIZE, + header->miniFATSectorsNumber * Sector::MINISECTOR_SIZE, zeroQueue, sourceStream, true @@ -1195,8 +1191,8 @@ void CompoundFile::AllocateMiniSectorChain(SVector §orChain) if (miniFAT.size() > 0) { rootStorage->getDirEntry()->setStartSetc(miniStream[0]->id); - header.miniFATSectorsNumber = miniFAT.size(); - header.firstMiniFATSectorID = miniFAT[0]->id; + header->miniFATSectorsNumber = miniFAT.size(); + header->firstMiniFATSectorID = miniFAT[0]->id; } } @@ -1216,7 +1212,7 @@ void CompoundFile::PersistMiniStreamToStream(const SVector &miniSectorCh { if (s->id == -1) - throw new CFException("Invalid minisector index"); + throw CFException("Invalid minisector index"); // Ministream sectors already allocated miniStreamView.Seek(Sector::MINISECTOR_SIZE * s->id, std::ios::beg); @@ -1246,6 +1242,11 @@ void CompoundFile::SetSectorChain(SVector sectorChain) } } +CFSVersion CompoundFile::getVersion() const +{ + return (CFSVersion)header->majorVersion; +} + SVector CompoundFile::GetDirectories() { return directoryEntries; @@ -1270,7 +1271,7 @@ void CompoundFile::ResetDirectoryEntry(int sid) void CompoundFile::InvalidateDirectoryEntry(int sid) { if (sid >= (int)directoryEntries.size()) - throw new CFException("Invalid SID of the directory entry to remove"); + throw CFException("Invalid SID of the directory entry to remove"); ResetDirectoryEntry(sid); } @@ -1280,7 +1281,7 @@ void CompoundFile::FreeAssociatedData(int sid) // Clear the associated stream (or ministream) if required if (directoryEntries[sid]->size > 0) //thanks to Mark Bosold for this ! { - if (directoryEntries[sid]->size < header.minSizeStandardStream) + if (directoryEntries[sid]->size < header->minSizeStandardStream) { SVector miniChain = GetSectorChain(directoryEntries[sid]->startSetc, SectorType::Mini); @@ -1302,37 +1303,37 @@ void CompoundFile::FreeData(CFStream *stream) SVector sectorChain; - if (stream->size() < header.minSizeStandardStream) + if (stream->size() < header->minSizeStandardStream) { - sectorChain = GetSectorChain(stream->dirEntry->getStartSetc(), SectorType::Mini); + sectorChain = GetSectorChain(stream->dirEntry.lock()->getStartSetc(), SectorType::Mini); FreeMiniChain(sectorChain, eraseFreeSectors); } else { - sectorChain = GetSectorChain(stream->dirEntry->getStartSetc(), SectorType::Normal); + sectorChain = GetSectorChain(stream->dirEntry.lock()->getStartSetc(), SectorType::Normal); FreeChain(sectorChain, 0, eraseFreeSectors); } - stream->dirEntry->setStartSetc(Sector::ENDOFCHAIN); - stream->dirEntry->setSize(0); + stream->dirEntry.lock()->setStartSetc(Sector::ENDOFCHAIN); + stream->dirEntry.lock()->setSize(0); } -void CompoundFile::WriteData(PCFItem cfItem, std::streamsize position, const std::vector &buffer) +void CompoundFile::WriteData(std::shared_ptr cfItem, std::streamsize position, const std::vector &buffer) { WriteData(cfItem, buffer, position, 0, buffer.size()); } -void CompoundFile::WriteData(PCFItem cfItem, const std::vector &buffer) +void CompoundFile::WriteData(std::shared_ptr cfItem, const std::vector &buffer) { WriteData(cfItem, 0, buffer); } -void CompoundFile::AppendData(PCFItem cfItem, const std::vector &buffer) +void CompoundFile::AppendData(std::shared_ptr cfItem, const std::vector &buffer) { WriteData(cfItem, cfItem->size(), buffer); } -void CompoundFile::SetStreamLength(PCFItem cfItem, std::streamsize length) +void CompoundFile::SetStreamLength(std::shared_ptr cfItem, std::streamsize length) { if (cfItem->size() == length) return; @@ -1340,7 +1341,7 @@ void CompoundFile::SetStreamLength(PCFItem cfItem, std::streamsize length) SectorType newSectorType = SectorType::Normal; int newSectorSize = GetSectorSize(); - if (length < header.minSizeStandardStream) + if (length < header->minSizeStandardStream) { newSectorType = SectorType::Mini; newSectorSize = Sector::MINISECTOR_SIZE; @@ -1349,7 +1350,7 @@ void CompoundFile::SetStreamLength(PCFItem cfItem, std::streamsize length) SectorType oldSectorType = SectorType::Normal; int oldSectorSize = GetSectorSize(); - if (cfItem->size() < header.minSizeStandardStream) + if (cfItem->size() < header->minSizeStandardStream) { oldSectorType = SectorType::Mini; oldSectorSize = Sector::MINISECTOR_SIZE; @@ -1359,7 +1360,7 @@ void CompoundFile::SetStreamLength(PCFItem cfItem, std::streamsize length) // Get Sector chain and delta size induced by client - SVector sectorChain = GetSectorChain(cfItem->dirEntry->getStartSetc(), oldSectorType); + SVector sectorChain = GetSectorChain(cfItem->dirEntry.lock()->getStartSetc(), oldSectorType); std::streamsize delta = length - cfItem->size(); // Check for transition ministream -> stream: @@ -1370,14 +1371,14 @@ void CompoundFile::SetStreamLength(PCFItem cfItem, std::streamsize length) bool transitionToNormal = false; SVector oldChain; - if (cfItem->dirEntry->getStartSetc() != Sector::ENDOFCHAIN) + if (cfItem->dirEntry.lock()->getStartSetc() != Sector::ENDOFCHAIN) { if ( - (length < header.minSizeStandardStream && cfItem->dirEntry->getSize() >= header.minSizeStandardStream) - || (length >= header.minSizeStandardStream && cfItem->dirEntry->getSize() < header.minSizeStandardStream) + (length < header->minSizeStandardStream && cfItem->dirEntry.lock()->getSize() >= header->minSizeStandardStream) + || (length >= header->minSizeStandardStream && cfItem->dirEntry.lock()->getSize() < header->minSizeStandardStream) ) { - if (cfItem->dirEntry->getSize() < header.minSizeStandardStream) + if (cfItem->dirEntry.lock()->getSize() < header->minSizeStandardStream) { transitionToNormal = true; oldChain = sectorChain; @@ -1422,13 +1423,13 @@ void CompoundFile::SetStreamLength(PCFItem cfItem, std::streamsize length) if (sectorChain.size() > 0) { - cfItem->dirEntry->setStartSetc(sectorChain[0]->id); - cfItem->dirEntry->setSize(length); + cfItem->dirEntry.lock()->setStartSetc(sectorChain[0]->id); + cfItem->dirEntry.lock()->setSize(length); } else { - cfItem->dirEntry->setStartSetc(Sector::ENDOFCHAIN); - cfItem->dirEntry->setSize(0); + cfItem->dirEntry.lock()->setStartSetc(Sector::ENDOFCHAIN); + cfItem->dirEntry.lock()->setSize(0); } } @@ -1445,8 +1446,8 @@ void CompoundFile::SetStreamLength(PCFItem cfItem, std::streamsize length) sv.reset(new StreamView(oldChain, oldSectorSize, oldSize, zeroQueue, sourceStream)); // Reset start sector and size of dir entry - cfItem->dirEntry->setStartSetc(Sector::ENDOFCHAIN); - cfItem->dirEntry->setSize(0); + cfItem->dirEntry.lock()->setStartSetc(Sector::ENDOFCHAIN); + cfItem->dirEntry.lock()->setSize(0); SVector newChain = GetMiniSectorChain(Sector::ENDOFCHAIN); StreamView destSv(newChain, Sector::MINISECTOR_SIZE, length, freeList, sourceStream); @@ -1481,13 +1482,13 @@ void CompoundFile::SetStreamLength(PCFItem cfItem, std::streamsize length) //Update dir item if (destSv.BaseSectorChain().size() > 0) { - cfItem->dirEntry->setStartSetc(destSv.BaseSectorChain()[0]->id); - cfItem->dirEntry->setSize(length); + cfItem->dirEntry.lock()->setStartSetc(destSv.BaseSectorChain()[0]->id); + cfItem->dirEntry.lock()->setSize(length); } else { - cfItem->dirEntry->setStartSetc(Sector::ENDOFCHAIN); - cfItem->dirEntry->setSize(0); + cfItem->dirEntry.lock()->setStartSetc(Sector::ENDOFCHAIN); + cfItem->dirEntry.lock()->setSize(0); } } else if (transitionToNormal) //############## TRANSITION TO NORMAL STREAM @@ -1530,13 +1531,13 @@ void CompoundFile::SetStreamLength(PCFItem cfItem, std::streamsize length) //Update dir item if (destSv.BaseSectorChain().size() > 0) { - cfItem->dirEntry->setStartSetc(destSv.BaseSectorChain()[0]->id); - cfItem->dirEntry->setSize(length); + cfItem->dirEntry.lock()->setStartSetc(destSv.BaseSectorChain()[0]->id); + cfItem->dirEntry.lock()->setSize(length); } else { - cfItem->dirEntry->setStartSetc(Sector::ENDOFCHAIN); - cfItem->dirEntry->setSize(0); + cfItem->dirEntry.lock()->setStartSetc(Sector::ENDOFCHAIN); + cfItem->dirEntry.lock()->setSize(0); } } } @@ -1551,7 +1552,7 @@ SList CompoundFile::FindFreeSectors(SectorType sType) SVector FatChain = GetSectorChain(-1, SectorType::FAT); - StreamView fatStream(FatChain, GetSectorSize(), header.fatSectorsNumber * GetSectorSize(), zeroQueue, sourceStream); + StreamView fatStream(FatChain, GetSectorSize(), header->fatSectorsNumber * GetSectorSize(), zeroQueue, sourceStream); int idx = 0; @@ -1577,9 +1578,9 @@ SList CompoundFile::FindFreeSectors(SectorType sType) } else { - SVector miniFAT = GetSectorChain(header.firstMiniFATSectorID, SectorType::Normal); + SVector miniFAT = GetSectorChain(header->firstMiniFATSectorID, SectorType::Normal); - StreamView miniFATView(miniFAT, GetSectorSize(), header.miniFATSectorsNumber * Sector::MINISECTOR_SIZE, zeroQueue, sourceStream); + StreamView miniFATView(miniFAT, GetSectorSize(), header->miniFATSectorsNumber * Sector::MINISECTOR_SIZE, zeroQueue, sourceStream); SVector miniStream = GetSectorChain(RootEntry()->getStartSetc(), SectorType::Normal); @@ -1616,10 +1617,10 @@ SList CompoundFile::FindFreeSectors(SectorType sType) return freeList; } -std::vector CompoundFile::GetData(CFStream *cFStream) +std::vector CompoundFile::GetData(const CFStream *cFStream) { if (_disposed) - throw new CFDisposedException("Compound File closed: cannot access data"); + throw CFDisposedException("Compound File closed: cannot access data"); std::vector result; @@ -1628,24 +1629,24 @@ std::vector CompoundFile::GetData(CFStream *cFStream) //IDirectoryEntry root = directoryEntries[0]; SList zeroQueue; - if (de->getSize() < header.minSizeStandardStream) + if (de.lock()->getSize() < header->minSizeStandardStream) { StreamView miniView(GetSectorChain( - de->getStartSetc(), + de.lock()->getStartSetc(), SectorType::Mini), Sector::MINISECTOR_SIZE, - de->getSize(), + de.lock()->getSize(), zeroQueue, sourceStream); - result.reserve(de->getSize()); + result.reserve(de.lock()->getSize()); miniView.Read(reinterpret_cast(result.data()), 0, result.size()); } else { - StreamView sView(GetSectorChain(de->getStartSetc(), SectorType::Normal), GetSectorSize(), de->getSize(), zeroQueue, sourceStream); + StreamView sView(GetSectorChain(de.lock()->getStartSetc(), SectorType::Normal), GetSectorSize(), de.lock()->getSize(), zeroQueue, sourceStream); - result.reserve((int)de->getSize()); + result.reserve((int)de.lock()->getSize()); sView.Read(reinterpret_cast(result.data()), 0, result.size()); @@ -1657,16 +1658,16 @@ std::vector CompoundFile::GetData(CFStream *cFStream) int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::vector &buffer, int count) { if (count > (int)buffer.size()) - throw new std::invalid_argument("count parameter exceeds buffer size"); + throw std::invalid_argument("count parameter exceeds buffer size"); - auto de = cFStream->dirEntry; + auto de = cFStream->dirEntry.lock(); count = std::min((std::streamsize)(de->getSize() - position), (std::streamsize)count); std::shared_ptr sView; SList zeroQueue; - if (de->getSize() < header.minSizeStandardStream) + if (de->getSize() < header->minSizeStandardStream) { sView.reset(new StreamView(GetSectorChain(de->getStartSetc(), SectorType::Mini), Sector::MINISECTOR_SIZE, de->getSize(), zeroQueue, sourceStream)); } @@ -1685,14 +1686,14 @@ int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::ve int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::vector &buffer, int offset, int count) { - auto de = cFStream->dirEntry; + auto de = cFStream->dirEntry.lock(); count = std::min((std::streamsize)(buffer.size() - offset), (std::streamsize)count); std::shared_ptr sView; SList zeroQueue; - if (de->getSize() < header.minSizeStandardStream) + if (de->getSize() < header->minSizeStandardStream) { sView.reset(new StreamView(GetSectorChain(de->getStartSetc(), SectorType::Mini), Sector::MINISECTOR_SIZE, de->getSize(), zeroQueue, sourceStream)); } @@ -1711,7 +1712,7 @@ int CompoundFile::ReadData(CFStream *cFStream, std::streamsize position, std::ve std::vector CompoundFile::GetDataBySID(int sid) { if (_disposed) - throw new CFDisposedException("Compound File closed: cannot access data"); + throw CFDisposedException("Compound File closed: cannot access data"); if (sid < 0) return {}; std::vector result; @@ -1719,7 +1720,7 @@ std::vector CompoundFile::GetDataBySID(int sid) { std::shared_ptr de = directoryEntries[sid]; SList zeroQueue; - if (de->getSize() < header.minSizeStandardStream) + if (de->getSize() < header->minSizeStandardStream) { StreamView miniView(GetSectorChain(de->getStartSetc(), SectorType::Mini), Sector::MINISECTOR_SIZE, de->getSize(), zeroQueue, sourceStream); result.reserve(de->getSize()); @@ -1742,9 +1743,9 @@ std::vector CompoundFile::GetDataBySID(int sid) GUID CompoundFile::getGuidBySID(int sid) { if (_disposed) - throw new CFDisposedException("Compound File closed: cannot access data"); + throw CFDisposedException("Compound File closed: cannot access data"); if (sid < 0) - throw new CFException("Invalid SID"); + throw CFException("Invalid SID"); std::shared_ptr de = directoryEntries[sid]; return de->getStorageCLSID(); } @@ -1752,9 +1753,9 @@ GUID CompoundFile::getGuidBySID(int sid) GUID CompoundFile::getGuidForStream(int sid) { if (_disposed) - throw new CFDisposedException("Compound File closed: cannot access data"); + throw CFDisposedException("Compound File closed: cannot access data"); if (sid < 0) - throw new CFException("Invalid SID"); + throw CFException("Invalid SID"); GUID g; //find first storage containing a non-zero CLSID before SID in directory structure for (int i = sid - 1; i >= 0; i--) @@ -1767,10 +1768,10 @@ GUID CompoundFile::getGuidForStream(int sid) return g; } -void CompoundFile::WriteData(PCFItem cfItem, const std::vector &buffer, std::streamsize position, int offset, int count) +void CompoundFile::WriteData(std::shared_ptr cfItem, const std::vector &buffer, std::streamsize position, int offset, int count) { - if (cfItem->dirEntry == nullptr) - throw new CFException("Internal error [cfItem->dirEntry] cannot be null"); + if (cfItem->dirEntry.expired()) + throw CFException("Internal error [cfItem->dirEntry] cannot be null"); if (buffer.size() == 0) return; @@ -1784,20 +1785,20 @@ void CompoundFile::WriteData(PCFItem cfItem, const std::vector &buffer, st SectorType _st = SectorType::Normal; int _sectorSize = GetSectorSize(); - if (cfItem->size() < header.minSizeStandardStream) + if (cfItem->size() < header->minSizeStandardStream) { _st = SectorType::Mini; _sectorSize = Sector::MINISECTOR_SIZE; } - SVector sectorChain = GetSectorChain(cfItem->dirEntry->getStartSetc(), _st); + SVector sectorChain = GetSectorChain(cfItem->dirEntry.lock()->getStartSetc(), _st); SList zeroQueue; StreamView sv(sectorChain, _sectorSize, newLength, zeroQueue, sourceStream); sv.Seek(position, std::ios::beg); sv.Write(reinterpret_cast(buffer.data()), offset, count); - if (cfItem->size() < header.minSizeStandardStream) + if (cfItem->size() < header->minSizeStandardStream) { PersistMiniStreamToStream(sv.BaseSectorChain()); //SetSectorChain(sv.BaseSectorChain); @@ -1806,7 +1807,7 @@ void CompoundFile::WriteData(PCFItem cfItem, const std::vector &buffer, st int CompoundFile::GetSectorSize() { - return 2 << (header.sectorShift - 1); + return 2 << (header->sectorShift - 1); } void CompoundFile::Dispose(bool disposing) @@ -1823,7 +1824,7 @@ void CompoundFile::Dispose(bool disposing) sectors.Clear(); rootStorage.reset(); // Some problem releasing resources... - header = Header(); + header.reset(); directoryEntries.clear(); fileName.clear(); } @@ -1903,10 +1904,10 @@ void CompoundFile::SetFileName(std::wstring fileName) void CompoundFile::LoadStream(Stream stream) { if (stream.get() == nullptr) - throw new CFException("Stream parameter cannot be null"); + throw CFException("Stream parameter cannot be null"); if (/*!stream.CanSeek*/false) - throw new CFException("Cannot load a non-seekable Stream"); + throw CFException("Cannot load a non-seekable Stream"); stream->seekp(0, std::ios::beg); diff --git a/Common/cppcf/compoundfile.h b/Common/cppcf/compoundfile.h index 407705a3f4..22b39516a2 100644 --- a/Common/cppcf/compoundfile.h +++ b/Common/cppcf/compoundfile.h @@ -1,18 +1,20 @@ #pragma once -#include "header.h" #include "sectorcollection.h" -#include "directoryentry.h" +#include "cfstorage.h" #include "slist.h" #include #include "RBTree/rbtree.h" #include "idirectoryentry.h" -#include "cfstream.h" -#include "cfstorage.h" #include + namespace CFCPP { + +class Header; +class DirectoryEntry; + enum CFSConfiguration { @@ -37,7 +39,7 @@ enum CFSUpdateMode Update }; -class CompoundFile : public std::enable_shared_from_this +class CompoundFile { public: CompoundFile(const std::wstring &fileName, CFSUpdateMode updateMode, CFSConfiguration configParameters); @@ -58,13 +60,13 @@ public: void InvalidateDirectoryEntry(int sid); void FreeAssociatedData(int sid); void FreeData(CFStream* stream); - void WriteData(PCFItem cfItem, const std::vector& buffer, std::streamsize position, int offset, int count); - void WriteData(PCFItem cfItem, std::streamsize position, const std::vector& buffer); - void WriteData(PCFItem cfItem, const std::vector& buffer); - void AppendData(PCFItem cfItem, const std::vector& buffer); - void SetStreamLength(PCFItem cfItem, std::streamsize length); + void WriteData(std::shared_ptr cfItem, const std::vector& buffer, std::streamsize position, int offset, int count); + void WriteData(std::shared_ptr cfItem, std::streamsize position, const std::vector& buffer); + void WriteData(std::shared_ptr cfItem, const std::vector& buffer); + void AppendData(std::shared_ptr cfItem, const std::vector& buffer); + void SetStreamLength(std::shared_ptr cfItem, std::streamsize length); SList FindFreeSectors(SectorType sType); - std::vector GetData(CFStream* cFStream); + std::vector GetData(const CFStream *cFStream); int ReadData(CFStream* cFStream, std::streamsize position, std::vector& buffer, int count); int ReadData(CFStream* cFStream, std::streamsize position, std::vector& buffer, int offset, int count); @@ -120,11 +122,11 @@ private: static int LowSaturation(int i); void SetSectorChain(SVector sectorChain); - inline CFSVersion getVersion() const {return (CFSVersion)header.majorVersion;} + CFSVersion getVersion() const; public: CFSConfiguration configuration = Default; - Header header; + std::unique_ptr
header; Stream sourceStream; private: diff --git a/Common/cppcf/directoryentry.cpp b/Common/cppcf/directoryentry.cpp index a930a66946..44d7b47157 100644 --- a/Common/cppcf/directoryentry.cpp +++ b/Common/cppcf/directoryentry.cpp @@ -65,10 +65,10 @@ void DirectoryEntry::SetEntryName(const std::wstring &entryName) entryName.find(L"/") == std::wstring::npos || entryName.find(L":") == std::wstring::npos || entryName.find(L"!") == std::wstring::npos - ) throw new CFException("Invalid character in entry: the characters '\\', '/', ':','!' cannot be used in entry name"); + ) throw CFException("Invalid character in entry: the characters '\\', '/', ':','!' cannot be used in entry name"); if (entryName.length() > 31) - throw new CFException("Entry name MUST NOT exceed 31 characters"); + throw CFException("Entry name MUST NOT exceed 31 characters"); std::copy(entryName.data(), entryName.data() + entryName.length(), this->entryName); @@ -95,8 +95,8 @@ void DirectoryEntry::Write(Stream stream) const rw.Write(child); rw.WriteArray(reinterpret_cast(&storageCLSID), sizeof (storageCLSID)); rw.Write(stateBits); - rw.WriteArray(creationDate, sizeof (creationDate)); - rw.WriteArray(modifyDate, sizeof (modifyDate)); + rw.WriteArray(reinterpret_cast(&creationDate), sizeof (creationDate)); + rw.WriteArray(reinterpret_cast(&modifyDate), sizeof (modifyDate)); rw.Write(startSetc); rw.Write(size); @@ -125,8 +125,8 @@ void DirectoryEntry::Read(Stream stream, CFSVersion ver) rw.ReadArray(reinterpret_cast(&storageCLSID), 16); stateBits = rw.Read(); - rw.ReadArray(creationDate, 8); - rw.ReadArray(modifyDate, 8); + rw.ReadArray(reinterpret_cast(&creationDate), 8); + rw.ReadArray(reinterpret_cast(&modifyDate), 8); startSetc = rw.Read(); if (ver == CFSVersion::Ver_3) @@ -220,7 +220,7 @@ int DirectoryEntry::CompareTo(const RedBlackTree::PIRBNode &other) const IDirectoryEntry* otherDir = dynamic_cast(other.get()); if (otherDir == nullptr) - throw new CFException("Invalid casting: compared object does not implement IDirectorEntry interface"); + throw CFException("Invalid casting: compared object does not implement IDirectorEntry interface"); if (this->getNameLength() > otherDir->getNameLength()) { @@ -273,7 +273,7 @@ std::shared_ptr DirectoryEntry::New(std::wstring name, StgType de->setSid(dirRepository.size() - 1); } else - throw new std::invalid_argument("dirRepository Directory repository cannot be null in New() method"); + throw std::invalid_argument("dirRepository Directory repository cannot be null in New() method"); return de; } diff --git a/Common/cppcf/header.cpp b/Common/cppcf/header.cpp index 036f30d46c..c474bcda1a 100644 --- a/Common/cppcf/header.cpp +++ b/Common/cppcf/header.cpp @@ -25,7 +25,7 @@ Header::Header(ushort version) break; default: - throw new CFException("Invalid Compound File Format version"); + throw CFException("Invalid Compound File Format version"); } @@ -102,7 +102,7 @@ void Header::Read(Stream stream) void Header::CheckVersion() const { if (majorVersion != 3 && majorVersion != 4) - throw new CFFileFormatException("Unsupported Binary File Format version: OpenMcdf only supports Compound Files with major version equal to 3 or 4 "); + throw CFFileFormatException("Unsupported Binary File Format version: OpenMcdf only supports Compound Files with major version equal to 3 or 4 "); } void Header::CheckSignature() const @@ -111,6 +111,6 @@ void Header::CheckSignature() const for (int i = 0; i < (int)headerSignature.size(); i++) { if (headerSignature[i] != OLE_CFS_SIGNATURE[i]) - throw new CFFileFormatException("Invalid OLE structured storage file"); + throw CFFileFormatException("Invalid OLE structured storage file"); } } diff --git a/Common/cppcf/streamview.cpp b/Common/cppcf/streamview.cpp index e0674d6bf8..66b336acd8 100644 --- a/Common/cppcf/streamview.cpp +++ b/Common/cppcf/streamview.cpp @@ -8,10 +8,10 @@ StreamView::StreamView(const SVector §orChain, int sectorSize, Strea : sectorSize(sectorSize), sectorChain(sectorChain), stream(stream) { // if (sectorChain == null) - // throw new CFException("Sector Chain cannot be null"); + // throw CFException("Sector Chain cannot be null"); if (sectorSize <= 0) - throw new CFException("Sector size must be greater than zero"); + throw CFException("Sector size must be greater than zero"); } StreamView::StreamView(const SVector §orChain, int sectorSize, std::streamsize length, @@ -125,7 +125,7 @@ std::streamsize StreamView::Read(char *buffer, std::streamsize offset, std::stre if (nToRead != 0) { - if (secIndex > (int)sectorChain.size()) throw new CFCorruptedFileException("The file is probably corrupted."); + if (secIndex > (int)sectorChain.size()) throw CFCorruptedFileException("The file is probably corrupted."); char* src = reinterpret_cast(sectorChain[secIndex]->GetData().data()); char* dst = buffer + offset + nRead; std::copy(src, src + nToRead, dst);