//
// aegis - project change supervisor
// Copyright (C) 2002-2006, 2008, 2012, 2014 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 .
//
#include
#include
#include
#include
#include
#include
input_catenate::~input_catenate()
{
trace(("%s\n{\n", __PRETTY_FUNCTION__));
if (selector < deeper.size())
deeper[selector]->pullback_transfer(this);
trace(("}\n"));
}
input_catenate::input_catenate(
const deeper_t &a_deeper,
bool a_delete_on_close
) :
deeper(a_deeper),
delete_on_close(a_delete_on_close),
selector(0),
pos(0)
{
trace(("%s\n", __PRETTY_FUNCTION__));
assert(deeper.size() > 0);
}
input_catenate::pointer
input_catenate::create(const deeper_t &a_deeper, bool a_delete_on_close)
{
trace(("%s\n", __PRETTY_FUNCTION__));
switch (a_deeper.size())
{
case 0:
return input_null::create();
case 1:
return a_deeper[0];
default:
break;
}
return pointer(new input_catenate(a_deeper, a_delete_on_close));
}
ssize_t
input_catenate::read_inner(void *data, size_t data_size)
{
trace(("%s\n{\n", __PRETTY_FUNCTION__));
size_t nbytes = 0;
for (;;)
{
trace(("data = %p\n", data));
trace(("data_size = %zd\n", data_size));
if (data_size == 0)
break;
trace(("selector = %zd/%zd\n", selector, deeper.size()));
if (selector >= deeper.size())
break;
input::pointer ip = deeper[selector];
trace(("ip->name() => %s\n", ip->name().quote_c().c_str()));
ssize_t n = ip->read(data, data_size);
trace(("n = %zd\n", n));
if (n < 0)
return -1;
if (n == 0)
++selector;
else
{
data = (void *)((char *)data + n);
data_size -= n;
nbytes += n;
}
}
pos += nbytes;
trace(("return %ld;\n", (long)nbytes));
trace(("}\n"));
return nbytes;
}
off_t
input_catenate::ftell_inner(void)
{
trace(("input_catenate::ftell_inner => %ld\n", (long)pos));
return pos;
}
nstring
input_catenate::name(void)
{
trace(("input_catenate::name\n"));
if (selector < deeper.size())
return deeper[selector]->name();
if (deeper.empty())
return "/dev/null";
return deeper.back()->name();
}
off_t
input_catenate::length(void)
{
off_t result = 0;
for (deeper_t::const_iterator it = deeper.begin(); it != deeper.end(); ++it)
{
off_t len = (*it)->length();
if (len < 0)
{
result = -1;
break;
}
result += len;
}
// fixme: the cast in the following statement should not be there.
trace(("input_catenate::length => %ld\n", (long)result));
return result;
}
void
input_catenate::keepalive(void)
{
for (deeper_t::const_iterator it = deeper.begin(); it != deeper.end(); ++it)
(*it)->keepalive();
}
bool
input_catenate::is_remote(void)
const
{
trace(("input_catenate::is_remote\n"));
if (selector < deeper.size())
return deeper[selector]->is_remote();
if (deeper.empty())
return false;
return deeper.back()->is_remote();
}
// vim: set ts=8 sw=4 et :