TAR archive iteration using range based for loops

Viewed 82

The job is to implement the TAR archive reader. As defined by the format, there are two types of blocks of defined size of 512B.

class tar {
public:
    class alignas( 512 ) header { 
        bool is_terminator( void ) { ... };
    };

    class alignas( 512 ) data { ... };
};

class tar_iterator {
public:
    using value_type = tar::data;
    using pointer = value_type *;

    tar_iterator( tar::header * header ) noexcept : m_header( header ) {}

    tar_iterator( nullptr_t ) noexcept : m_header( nullptr ) {}

    /* Prefix increment operator */
    tar_iterator & operator++( void ) noexcept {
        m_header = m_header->next();
        return *this;
    }

    /* Postfix increment operator */
    tar_iterator operator++( int ) noexcept {
        tar_iterator temp { *this };
        m_header = m_header->next();
        return temp;
    }

    /* TODO: Dereference operator shall access the stored file */
    tar::data * operator*( void ) const noexcept {

    }


    bool operator==( const tar_iterator & other ) const noexcept {
        return m_header == other.m_header;
    }

    bool operator!=( const tar_iterator & other ) const noexcept {
        return m_header != other.m_header;
    }

    tar::header * get( void ) const {
        return m_header;
    }

    tar_iterator get_next( void ) const noexcept {
        if( m_header != nullptr ) {
            return tar_iterator { m_header->next() };
        } else {
            return tar_iterator { nullptr };
        }
    }

private:
    tar::header * m_header;
};

class tar_fs {
public:
    tar_iterator begin( void ) {
        return { m_start };
    }

    tar_iterator end( void ) {
        /* TODO: <------------ HERE COMES THE MAGIC */
    }

private:
    tar::header * m_start { nullptr }
};

TAR format is just a stream of 512B long blocks which is either the header or the data. One header is followed by one or more data blocks. As a result, it is unknown how many files are within unless the whole TAR archive is iterated and manually counted.

The question is: How to implement the tar_fs::end() member function if the header count is not known explicitly? Is there any other way of implementing the mandatory functions to make tar_fs supporting range based for loops to iterate over all the tar::headers? The end of the archive is identified by a all-zeroes block (512B) - the terminator - the header provides the information using tar::header::is_terminator().

0 Answers
Related