0

I'm currently playing with an idea of recursive reader/unpacker of various "mountable" fileformats. It should for example allow to read zipped file stored in vmdk file stored in NTFS directory structure.

Currently I have only this header, where I use CZipMounter.mount to load and pre-parse zip file in memory - this fills private list of file info in vecEntries (and a set of not-yet mentioned zip parsing variables). Then the caller calls CZipMounter.openDir, which returns the iterator object reference (~equivalent of POSIX DIR). CZipIterator must have access to CZipMounter (at least I think it has to, there is a handle open to underlying file, handle to un-zip library etc). Then the caller can call CZipIterator.readDir in while loop. When CZipIterator instance is destroyed, it's an equivalent of POSIX CloseDir.

And now I'm lost regarding to scoping/lifetime problems of CZipMounter. Because if it gets destroyed prematurely, all CZipIterator instances would have pointers (or references, it does not matter IMO) pointing to already destroyed object.

Basically I may have two completely different questions:

  1. Is there any better way how to implement this kind of recursion here? I somehow wouldn't think that's it's a good idea to copy needed data from Mounter to Iterator.
  2. If my example does make sense, how to prevent CZipMounter from premature destruction (ie. I want CZipMounter to be destroyed after all `CZipIterator~ instances.

The whole thing is planned to be slightly more complicated as there would be more CXXXMounter classes and one virtual CMotherOfAllMounters class.

enum commonDirTypes
{
    myFILE = 0,
    myDIR = 1
};

struct commonDirEntry
{
    std::string entryName;
    enum commonDirTypes entryType;
};

struct zipDirEntry : commonDirEntry
{
    std::vector<zipDirEntry> vecEntries;
};

class CZipMounter;

class CZipIterator
{
    public:
        //readDir must return type of object and whether or not we can continue reading
        struct zipDirEntry* readDir();
    private:
        CZipMounter* pMount;
};

class CZipMounter
{
    public:
        bool mount(const char*);
        CZipIterator& openDir(const char*);
    private:
        std::vector<zipDirEntry> vecEntries;
};
  • How about shared_ptr? – user253751 Jun 30 '21 at 16:15
  • Or a listener from the iterator to the mounter class, so that you can invalidate the iterator if the mounter goes out of scope? (quite similar to the shared_ptr solution, maybe closer to weak_ptr on the iterator?) – Matthieu Brucher Jun 30 '21 at 16:17
  • Regarding shared_ptr - would I need to make sure that CZipMounter instance is not done this way: `CZipMounter czm; czm.mount(...);` but somehow like `auto czm = std::shared_ptr(new CZipMounter());` ...and then inside openDir I'd pass `this` into `CZipIterator` like std::shared_ptr(this)? Is my understanding correct? I got little bit rusty with C++ and never used smart pointers. – Jindroush Jun 30 '21 at 16:58

0 Answers0