1 #ifndef IMAGE_IO_BASE_DATA_CONTEXT_H_ // NOLINT 2 #define IMAGE_IO_BASE_DATA_CONTEXT_H_ // NOLINT 3 4 #include <list> 5 #include <string> 6 7 #include "image_io/base/data_line_map.h" 8 #include "image_io/base/data_range.h" 9 #include "image_io/base/data_segment.h" 10 11 namespace photos_editing_formats { 12 namespace image_io { 13 14 /// A class to represent a position in a textual subrange of a DataSegment, and 15 /// a means to create an usable error message that shows the relevant line 16 /// number and line text and the location as a "caret" position. The class also 17 /// provides a list of names that can be used to add context to the errors. 18 class DataContext { 19 public: 20 /// @param location A location in the data segment. 21 /// @param range A subrange of the data segment's range. 22 /// @param data_line_map A map for obtaining the line number and range given 23 /// the location. DataContext(size_t location,const DataRange & range,const DataSegment & segment,const DataLineMap & data_line_map)24 DataContext(size_t location, const DataRange& range, 25 const DataSegment& segment, const DataLineMap& data_line_map) 26 : location_(location), 27 range_(range), 28 segment_(segment), 29 line_info_map_(data_line_map) {} 30 31 /// @return The location of the context. GetLocation()32 size_t GetLocation() const { return location_; } 33 34 /// @param location A new value to use to set the location of the context. SetLocation(size_t location)35 void SetLocation(size_t location) { location_ = location; } 36 37 /// @param delta A delta value that is added to the location of the context. 38 /// @return The new location of the context. IncrementLocation(size_t delta)39 size_t IncrementLocation(size_t delta) { 40 location_ += delta; 41 return location_; 42 } 43 44 /// @return The range of the data segment defined by this context. GetRange()45 const DataRange& GetRange() const { return range_; } 46 47 /// @param range Sets a new range to use for this context. SetRange(const DataRange & range)48 void SetRange(const DataRange& range) { range_ = range; } 49 50 /// @return The data segment of this context. GetSegment()51 const DataSegment& GetSegment() const { return segment_; } 52 53 /// @return The line info map of this context. GetDataLineMap()54 const DataLineMap& GetDataLineMap() const { return line_info_map_; } 55 56 /// @return Whether the context's location and range are valid for use with 57 /// the data segment's range. IsValidLocationAndRange()58 bool IsValidLocationAndRange() const { 59 return range_.IsValid() && range_.Contains(location_) && 60 segment_.GetDataRange().Contains(range_); 61 } 62 63 /// @return A pointer to the data segment's buffer, cast as a const char* type 64 /// pointer, or nullptr if the location and/or range are invalid. GetCharBytes()65 const char* GetCharBytes() const { 66 return IsValidLocationAndRange() 67 ? reinterpret_cast<const char*>(segment_.GetBuffer(location_)) 68 : nullptr; 69 } 70 71 /// @return The number of bytes available from the location of the context to 72 /// the end of the context's range, or 0 if the location and/or range are 73 /// invalid. GetBytesAvailable()74 size_t GetBytesAvailable() const { 75 return IsValidLocationAndRange() ? range_.GetEnd() - location_ : 0; 76 } 77 78 /// @return The context's name list that is used when creating error messages. GetNameList()79 std::list<std::string>& GetNameList() { return name_list_; } 80 81 /// @return The context's name list that is used when creating error messages. GetNameList()82 const std::list<std::string>& GetNameList() const { return name_list_; } 83 84 /// @return An error message that describes the location/range data segment 85 /// range that leads to the IsValidLocationRange() function returning false. 86 /// Great to user for internal error messages. 87 std::string GetInvalidLocationAndRangeErrorText() const; 88 89 /// @return An error message with the given descriptions for the error and the 90 /// expectation. See the other GetErrorText() function documentation for more 91 /// details on the format of the error messsage. 92 std::string GetErrorText(const std::string& error_description, 93 const std::string& expectation_description) const; 94 95 /// @return An error message with the given descriptions for the error and the 96 /// expectation. The format of the error message is: 97 /// error_description 98 /// - prefix_name_list:name_list:postfix_name_list: 99 /// - at line:number:line_contents 100 /// - ^expected:expectation_description 101 /// If error_description is empty then the first line containing it is not 102 /// written. If expectation_description is empty, then the expected:... part 103 /// of the last line is not written. If the context's name list, and the 104 /// pre/postfix name lists are all empty, then that line is not written. 105 std::string GetErrorText(const std::list<std::string>& prefix_name_list, 106 const std::list<std::string>& postfix_name_list, 107 const std::string& error_description, 108 const std::string& expectation_description) const; 109 110 private: 111 /// @return The string with the contents of the prefix_name_list, name_list_ 112 /// and the postfix namelist concatenated with a ":" separator. 113 std::string GetNamesString( 114 const std::list<std::string>& prefix_name_list, 115 const std::list<std::string>& postfix_name_list) const; 116 117 /// @return The line number string of the form line:XX, where XX is the data 118 /// line's number or "?" if the nmber is zero. 119 std::string GetLineNumberString(const DataLine& data_line) const; 120 121 /// Gets the clipped and line ranges using the data line's range value. 122 void GetClippedAndLineRange(const DataLine& data_line, 123 DataRange* clipped_range, 124 DataRange* line_range) const; 125 126 /// Gets the line string using the clipped and line ranges and updates the 127 /// number of spaces before the caret depending on the contents of the line. 128 std::string GetLineString(const DataRange& clipped_range, 129 const DataRange& line_range, 130 size_t* spaces_before_caret) const; 131 132 /// See the constructor for documentation on the data members. 133 size_t location_; 134 DataRange range_; 135 const DataSegment& segment_; 136 const DataLineMap& line_info_map_; 137 std::list<std::string> name_list_; 138 }; 139 140 } // namespace image_io 141 } // namespace photos_editing_formats 142 143 #endif // IMAGE_IO_BASE_DATA_CONTEXT_H_ // NOLINT 144