// // 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 :