Created
June 13, 2018 16:07
-
-
Save royvandam/82363d511fa35f361be0a2e14af6ac18 to your computer and use it in GitHub Desktop.
C++11 cross platform tail class for tailing streams
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <fstream> | |
#include <vector> | |
#include <istream> | |
#include <chrono> | |
#include <thread> | |
class Tail { | |
public: | |
Tail(std::istream & stream, uint32_t interval = 250) | |
: stream(stream) | |
, interval(interval) | |
{} | |
template<class Clock, class Duration> | |
bool ReadLine(std::string & line, const std::chrono::time_point<Clock, Duration>& deadline) | |
{ | |
while (!std::getline(stream, line)) { | |
auto next = std::chrono::system_clock::now() + interval; | |
if (next > deadline) | |
return false; | |
std::this_thread::sleep_until(next); | |
stream.clear(); | |
} | |
return true; | |
} | |
bool ReadLine(std::string & line, uint32_t timeout) | |
{ | |
auto deadline = std::chrono::system_clock::now() + | |
std::chrono::milliseconds(timeout); | |
return ReadLine(line, deadline); | |
} | |
bool ReadUntil(std::string const& needle, std::vector<std::string>& lines, | |
uint32_t timeout) | |
{ | |
auto deadline = std::chrono::system_clock::now() + | |
std::chrono::milliseconds(timeout); | |
std::string line; | |
while (ReadLine(line, deadline)) { | |
lines.push_back(line); | |
if (line.find(needle) != std::string::npos) { | |
return true; | |
} | |
} | |
return false; | |
} | |
protected: | |
std::istream& stream; | |
std::chrono::milliseconds interval; | |
}; | |
int main(int argc, char* argv[]) { | |
if (argc != 2) { | |
std::cerr << "Usage: " << argv[0] << " filename" << std::endl; | |
return 1; | |
} | |
std::fstream file(argv[1], file.in); | |
if (!file.is_open()) { | |
std::cerr << "Failed to open file: " << argv[1] << std::endl; | |
return 2; | |
} | |
Tail tail(file); | |
std::vector<std::string> lines; | |
if (!tail.ReadUntil("foobar", lines, 10000)) { | |
std::cout << "timeout" << std::endl; | |
return 0; | |
} | |
for (auto line: lines) { | |
std::cout << line << std::endl; | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment