1 #ifndef TCPSPSUITE_FILETOOLS_HPP
2 #define TCPSPSUITE_FILETOOLS_HPP
18 LineStorage(std::ifstream & f_in) : f(f_in) { this->read_lines(); }
21 line_at_byte(
size_t byte)
const noexcept
23 auto line_it = std::upper_bound(this->byte_prefix_sum.begin(),
24 this->byte_prefix_sum.end(),
byte);
27 auto line_count = std::distance(this->byte_prefix_sum.begin(), line_it) - 1;
28 assert(line_count >= 0);
29 return static_cast<size_t>(line_count);
33 get_line(
size_t index)
const
35 return this->lines.at(index);
39 get_line_byte_prefix_sum(
size_t index)
const
41 return this->byte_prefix_sum.at(index);
45 line_count() const noexcept
47 return this->lines.size();
54 auto old_streampos = this->f.tellg();
57 for (std::string s; std::getline(this->f, s);) {
59 this->byte_prefix_sum.push_back(
static_cast<size_t>(this->f.tellg()));
60 this->lines.push_back(s);
64 this->f.seekg(old_streampos);
67 std::vector<std::string> lines;
68 std::vector<size_t> byte_prefix_sum;
71 class FileContextGiver {
73 FileContextGiver(std::string filename_in,
size_t byte_in,
74 size_t context_lines = 3)
75 : byte(byte_in), context(context_lines), filename(std::move(filename_in)),
78 this->build_context();
81 const std::vector<std::string> &
82 get_message() const noexcept
91 size_t relevant_line = this->ls.line_at_byte(this->
byte);
92 for (
size_t l =
static_cast<size_t>(
93 std::max(0l,
static_cast<long>(relevant_line) -
94 static_cast<long>(this->context)));
95 l < relevant_line; ++l) {
98 this->add_line(relevant_line);
99 this->add_indicator(relevant_line,
byte);
101 for (
size_t l = relevant_line + 1;
102 l < std::min(this->ls.line_count(), relevant_line + this->context + 1);
109 add_line(
size_t index)
111 std::ostringstream line;
112 line << std::setfill(
' ') << std::setw(4) << index <<
" | ";
113 std::string raw_line = this->ls.get_line(index);
114 std::replace(raw_line.begin(), raw_line.end(),
'\t',
' ');
116 this->message.push_back(line.str());
120 add_indicator(
size_t line_index,
size_t at_byte)
122 size_t indent = at_byte - this->ls.get_line_byte_prefix_sum(line_index);
123 std::ostringstream indicator;
124 std::string prefix(indent + 7,
' ');
127 this->message.push_back(indicator.str());
132 std::string filename;
136 std::vector<std::string> message;