#include "image_io/base/data_line_map.h" #include 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