blob: 06ecfd9d19c8b43ea59f8293c6a87de8d7f69cd2 [file] [log] [blame]
#include "image_io/base/data_line_map.h"
#include <algorithm>
namespace photos_editing_formats {
namespace image_io {
size_t DataLineMap::GetDataLineCount() const { return data_lines_.size(); }
DataLine DataLineMap::GetDataLine(size_t location) const {
if (data_lines_.empty()) {
return DataLine();
}
DataLine key(0, DataRange(location, location));
auto not_less_pos =
std::lower_bound(data_lines_.begin(), data_lines_.end(), key,
[](const DataLine& lhs, const DataLine& rhs) {
return lhs.range.GetBegin() < rhs.range.GetBegin();
});
if (not_less_pos == data_lines_.end()) {
--not_less_pos;
} else if (not_less_pos != data_lines_.begin()) {
auto prev_pos = not_less_pos - 1;
if (location < prev_pos->range.GetEnd()) {
not_less_pos = prev_pos;
}
}
if (not_less_pos->range.Contains(location)) {
return *not_less_pos;
}
return DataLine();
}
void DataLineMap::FindDataLines(const DataRange& range,
const DataSegment& segment) {
size_t line_end;
size_t range_end = range.GetEnd();
size_t line_begin = range.GetBegin();
size_t next_number = GetDataLineCount() + 1;
while (line_begin < range_end) {
line_end = std::min(range_end, segment.Find(line_begin, '\n'));
if (last_line_incomplete_ && !data_lines_.empty()) {
line_begin = data_lines_.back().range.GetBegin();
data_lines_.back().range = DataRange(line_begin, line_end);
if (line_end < range_end &&
segment.GetValidatedByte(line_end).value == '\n') {
last_line_incomplete_ = false;
}
} else {
data_lines_.emplace_back(next_number++, DataRange(line_begin, line_end));
}
line_begin = line_end + 1;
}
last_line_incomplete_ =
line_end == range_end || segment.GetValidatedByte(line_end).value != '\n';
}
void DataLineMap::Clear() {
data_lines_.clear();
last_line_incomplete_ = false;
}
} // namespace image_io
} // namespace photos_editing_formats