aboutsummaryrefslogtreecommitdiff
path: root/third_party/image_io/includes/image_io/xml/xml_reader.h
blob: 905d07221621816aa0dcd1f8540dac2fc675c9b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef IMAGE_IO_XML_XML_READER_H_  // NOLINT
#define IMAGE_IO_XML_XML_READER_H_  // NOLINT

#include <memory>
#include <string>
#include <vector>

#include "image_io/base/data_line_map.h"
#include "image_io/base/data_match_result.h"
#include "image_io/base/message_handler.h"
#include "image_io/xml/xml_handler_context.h"
#include "image_io/xml/xml_rule.h"

namespace photos_editing_formats {
namespace image_io {

/// A class for reading and parsing the text of a data segment, resulting in the
/// functions of an XmlHandler to be called. This reader's Parse() function can
/// be called multiple times for text that spans multiple data segments. Errors
/// are reported to the message handler as they are encountered. In general,
/// there will be three types of errors: internal (programming), syntax, and
/// value errors. Internal errors can come from any where in this code base;
/// Only one such error is permitted per StartParse/Parse... sequence. Syntax
/// errors are usually issued by XmlRule instances; like internal errors, only
/// one such error is tolerated per StartParse/Parse... sequence. XmlHandler
/// functions may issue value errors; multiple such value errors are tolerated.
class XmlReader {
 public:
  XmlReader(XmlHandler* handler, MessageHandler* message_handler)
      : handler_(handler),
        message_handler_(message_handler),
        data_line_map_(&internal_data_line_map_),
        bytes_parsed_(0),
        has_internal_or_syntax_error_(false),
        has_errors_(false) {}

  /// A externally initialized data line map can be used for error messages
  /// instead of the internally built map. Otherwise the internal map will be
  /// used.
  /// @param data_line_map The pre-initialized data line map to use.
  void SetDataLineMap(const DataLineMap* data_line_map) {
    data_line_map_ = data_line_map;
  }

  /// Sets up the reader for parsing data segment text using the given XmlRule.
  /// @param rule The top level rule to use when parsing the data segment text.
  /// @return Whether the reader was set up propertly.
  bool StartParse(std::unique_ptr<XmlRule> rule);

  /// Parses the text portion of the data segment starting at a location. This
  /// function may be called multiple times for text that spans multiple data
  /// segments.
  /// @param start_location The location at which to start reading/parsing.
  /// This location must be contained in the range parameter.
  /// @param range The portion of the data segment to parse. This range value
  /// must be contained in the range returned by DataSegment::GetRange()
  /// @param segment The segment containing the text to parse.
  /// @return Whether the reading/parsing was successful.
  bool Parse(size_t start_location, const DataRange& range,
             const DataSegment& segment);

  /// Parses the string value. This is an alternate way to parse XML syntax.
  /// Internally, this function uses the string to create a data segment and
  /// calls the Parse(start_location, range, segment) function. The range is
  /// computed like this: [GetBytesParsed(), GetBytesParsed() + value.length()).
  /// @param value The string value containing XML syntax to parse.
  /// @return Whether the reading/parsing was successful.
  bool Parse(const std::string& value);

  /// Finishes up the reading/parsing process. The rule passed to StartParse()
  /// must have consumed all the text of the segments and be "done", otherwise
  /// this function will issue a kPrematureEndOfDataError type error message.
  /// @param Whether the reading/parsing operation was completed successfully.
  bool FinishParse();

  /// @return The total number of bytes of text that have been read/parsed.
  size_t GetBytesParsed() const { return bytes_parsed_; }

  /// @return Whether errors have been encountered in reading/parsing the text.
  /// This value may be different from the value returned by the Parse() and
  /// FinishParse() functions. Those functions take into account only internal
  /// and syntax type errors. This value includes all other types of errors.
  bool HasErrors() const { return has_errors_; }

  /// @return The handler that handles the output of the parsing operations.
  XmlHandler* GetHandler() const { return handler_; }

 private:
  /// Sets up the context's name list that is used when creating error message.
  /// @parma context The context to set up.
  void InitializeContextNameList(XmlHandlerContext* context);

  /// If the result has a message, reports it otherwise does nothing.
  /// @param result The result value for an XmlRule::Parse function.
  void ReportMessageIfNeeded(const DataMatchResult& result);

  /// Reports the message indicated in the result to the message handler and
  /// updates the data boolean data members indicating errors.
  /// @param result The result value for an XmlRule::Parse function.
  /// @param context The context for generating an error message if needed.
  void ReportError(const DataMatchResult& result, const DataContext& context);

  /// Reports the message to the message handler and updates the data boolean
  /// data members indicating errors.
  /// @param message The message to send to the message handler.
  void ReportError(const Message& message);

  /// The reader's handler.
  XmlHandler* handler_;

  /// An optional message handler to write messages to.
  MessageHandler* message_handler_;

  /// A possibly externally initialized data line map used for error messages.
  const DataLineMap* data_line_map_;

  /// An internal data line map used for error message creation if an externally
  /// defined map is not provided.
  DataLineMap internal_data_line_map_;

  /// The pending and active rules.
  std::vector<std::unique_ptr<XmlRule>> rule_stack_;

  /// The total number of bytes that have been parsed.
  size_t bytes_parsed_;

  /// Whether an internal or syntax error has occurred.
  bool has_internal_or_syntax_error_;

  /// Whether any type of error has occurred.
  bool has_errors_;
};

}  // namespace image_io
}  // namespace photos_editing_formats

#endif  // IMAGE_IO_XML_XML_READER_H_  // NOLINT