1 #include "image_io/base/data_line_map.h" 2 3 #include <algorithm> 4 5 namespace photos_editing_formats { 6 namespace image_io { 7 8 size_t DataLineMap::GetDataLineCount() const { return data_lines_.size(); } 9 10 DataLine DataLineMap::GetDataLine(size_t location) const { 11 if (data_lines_.empty()) { 12 return DataLine(); 13 } 14 DataLine key(0, DataRange(location, location)); 15 auto not_less_pos = 16 std::lower_bound(data_lines_.begin(), data_lines_.end(), key, 17 [](const DataLine& lhs, const DataLine& rhs) { 18 return lhs.range.GetBegin() < rhs.range.GetBegin(); 19 }); 20 if (not_less_pos == data_lines_.end()) { 21 --not_less_pos; 22 } else if (not_less_pos != data_lines_.begin()) { 23 auto prev_pos = not_less_pos - 1; 24 if (location < prev_pos->range.GetEnd()) { 25 not_less_pos = prev_pos; 26 } 27 } 28 if (not_less_pos->range.Contains(location)) { 29 return *not_less_pos; 30 } 31 return DataLine(); 32 } 33 34 void DataLineMap::FindDataLines(const DataRange& range, 35 const DataSegment& segment) { 36 size_t line_end; 37 size_t range_end = range.GetEnd(); 38 size_t line_begin = range.GetBegin(); 39 size_t next_number = GetDataLineCount() + 1; 40 while (line_begin < range_end) { 41 line_end = std::min(range_end, segment.Find(line_begin, '\n')); 42 if (last_line_incomplete_ && !data_lines_.empty()) { 43 line_begin = data_lines_.back().range.GetBegin(); 44 data_lines_.back().range = DataRange(line_begin, line_end); 45 if (line_end < range_end && 46 segment.GetValidatedByte(line_end).value == '\n') { 47 last_line_incomplete_ = false; 48 } 49 } else { 50 data_lines_.emplace_back(next_number++, DataRange(line_begin, line_end)); 51 } 52 line_begin = line_end + 1; 53 } 54 last_line_incomplete_ = 55 line_end == range_end || segment.GetValidatedByte(line_end).value != '\n'; 56 } 57 58 void DataLineMap::Clear() { 59 data_lines_.clear(); 60 last_line_incomplete_ = false; 61 } 62 63 } // namespace image_io 64 } // namespace photos_editing_formats 65