//
// tardy - a tar post-processor
// Copyright (C) 2009, 2011 Peter Miller
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

#include <libtardy/gmatch.h>
#include <libtardy/tar/input/filter/exclude.h>


tar_input_filter_exclude::~tar_input_filter_exclude()
{
}


tar_input_filter_exclude::tar_input_filter_exclude(
    const tar_input::pointer &a_deeper,
    const rcstring &a_glob
) :
    tar_input_filter(a_deeper),
    glob(a_glob)
{
}


tar_input::pointer
tar_input_filter_exclude::create(const tar_input::pointer &a_deeper,
    const rcstring &a_glob)
{
    return pointer(new tar_input_filter_exclude(a_deeper, a_glob));
}


bool
tar_input_filter_exclude::read_header(tar_header &h)
{
    for (;;)
    {
        if (!tar_input_filter::read_header(h))
            return false;
        bool toss =
            (
                gmatch(glob, h.name)
            ||
                (
                    h.type == tar_header::type_directory
                &&
                    gmatch(glob, h.name + "/")
                )
            );
        if (!toss)
            return true;
        tar_input_filter::read_header_padding();

        //
        // Read and discard the file data.
        //
        size_t n = h.size;
        while (n > 0)
        {
            char dummy[1024];
            size_t chunk_max = n;
            if (chunk_max > sizeof(dummy))
                chunk_max = sizeof(dummy);
            int chunk = tar_input_filter::read_data(dummy, chunk_max);
            if (chunk == 0)
                tar_input_filter::fatal("premature end of file");
            n -= chunk_max;
        }
        tar_input_filter::read_data_padding();
    }
}
