| | #include "util/stream/line_input.hh" |
| |
|
| | #include "util/exception.hh" |
| | #include "util/file.hh" |
| | #include "util/read_compressed.hh" |
| | #include "util/stream/chain.hh" |
| |
|
| | #include <algorithm> |
| | #include <vector> |
| |
|
| | namespace util { namespace stream { |
| |
|
| | void LineInput::Run(const ChainPosition &position) { |
| | ReadCompressed reader(fd_); |
| | |
| | std::vector<char> carry; |
| |
|
| | for (Link block(position); ; ++block) { |
| | char *to = static_cast<char*>(block->Get()); |
| | char *begin = to; |
| | char *end = to + position.GetChain().BlockSize(); |
| | std::copy(carry.begin(), carry.end(), to); |
| | to += carry.size(); |
| | while (to != end) { |
| | std::size_t got = reader.Read(to, end - to); |
| | if (!got) { |
| | |
| | block->SetValidSize(to - begin); |
| | ++block; |
| | block.Poison(); |
| | return; |
| | } |
| | to += got; |
| | } |
| |
|
| | |
| | char *newline; |
| | for (newline = to - 1; ; --newline) { |
| | UTIL_THROW_IF(newline < begin, Exception, "Did not find a newline in " << position.GetChain().BlockSize() << " bytes of input of " << NameFromFD(fd_) << ". Is this a text file?"); |
| | if (*newline == '\n') break; |
| | } |
| |
|
| | |
| | carry.clear(); |
| | carry.resize(to - (newline + 1)); |
| | std::copy(newline + 1, to, &*carry.begin()); |
| |
|
| | block->SetValidSize(newline + 1 - begin); |
| | } |
| | } |
| |
|
| | }} |
| |
|