1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_XML_PARSER_H_
6#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_XML_PARSER_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "base/memory/scoped_ptr.h"
14#include "components/autofill/core/browser/autofill_server_field_info.h"
15#include "components/autofill/core/browser/field_types.h"
16#include "components/autofill/core/browser/form_structure.h"
17#include "third_party/webrtc/libjingle/xmllite/xmlparser.h"
18
19namespace autofill {
20
21// The base class that contains common functionality between
22// AutofillQueryXmlParser and AutofillUploadXmlParser.
23class AutofillXmlParser : public buzz::XmlParseHandler {
24 public:
25  AutofillXmlParser();
26  virtual ~AutofillXmlParser();
27
28  // Returns true if no parsing errors were encountered.
29  bool succeeded() const { return succeeded_; }
30
31 private:
32  // A callback for the end of an </element>, called by Expat.
33  // |context| is a parsing context used to resolve element/attribute names.
34  // |name| is the name of the element.
35  virtual void EndElement(buzz::XmlParseContext* context,
36                          const char* name) OVERRIDE;
37
38  // The callback for character data between tags (<element>text...</element>).
39  // |context| is a parsing context used to resolve element/attribute names.
40  // |text| is a pointer to the beginning of character data (not null
41  // terminated).
42  // |len| is the length of the string pointed to by text.
43  virtual void CharacterData(buzz::XmlParseContext* context,
44                             const char* text,
45                             int len) OVERRIDE;
46
47  // The callback for parsing errors.
48  // |context| is a parsing context used to resolve names.
49  // |error_code| is a code representing the parsing error.
50  virtual void Error(buzz::XmlParseContext* context,
51                     XML_Error error_code) OVERRIDE;
52
53  // True if parsing succeeded.
54  bool succeeded_;
55
56  DISALLOW_COPY_AND_ASSIGN(AutofillXmlParser);
57};
58
59// The XML parse handler for parsing Autofill query responses.  A typical
60// response looks like:
61//
62// <autofillqueryresponse experimentid="1">
63//   <field autofilltype="0" />
64//   <field autofilltype="1" />
65//   <field autofilltype="3" />
66//   <field autofilltype="2" />
67// </autofillqueryresponse>
68//
69// Fields are returned in the same order they were sent to the server.
70// autofilltype: The server's guess at what type of field this is.  0
71// is unknown, other types are documented in
72// components/autofill/core/browser/field_types.h.
73// Experiment ids are currently ignored.
74class AutofillQueryXmlParser : public AutofillXmlParser {
75 public:
76  AutofillQueryXmlParser(std::vector<AutofillServerFieldInfo>* field_infos,
77                         UploadRequired* upload_required);
78  virtual ~AutofillQueryXmlParser();
79
80 private:
81  // A callback for the beginning of a new <element>, called by Expat.
82  // |context| is a parsing context used to resolve element/attribute names.
83  // |name| is the name of the element.
84  // |attrs| is the list of attributes (names and values) for the element.
85  virtual void StartElement(buzz::XmlParseContext* context,
86                            const char* name,
87                            const char** attrs) OVERRIDE;
88
89  // A helper function to parse a |WebElementDescriptor|.
90  // |context| is the current parsing context.
91  // |attrs| is the list of attributes (names and values) for the element.
92  // |element_descriptor| will be populated by this function.
93  void ParseElementDescriptor(buzz::XmlParseContext* context,
94                              const char* const* attrs,
95                              WebElementDescriptor* element_descriptor);
96
97  // A helper function to retrieve integer values from strings.  Raises an
98  // XML parse error if it fails.
99  // |context| is the current parsing context.
100  // |value| is the string to convert.
101  int GetIntValue(buzz::XmlParseContext* context, const char* attribute);
102
103  // The parsed <field type, default value> pairs.
104  std::vector<AutofillServerFieldInfo>* field_infos_;
105
106  // A flag indicating whether the client should upload Autofill data when this
107  // form is submitted.
108  UploadRequired* upload_required_;
109
110  DISALLOW_COPY_AND_ASSIGN(AutofillQueryXmlParser);
111};
112
113// The XML parser for handling Autofill upload responses.  Typical upload
114// responses look like:
115//
116// <autofilluploadresponse negativeuploadrate="0.00125" positiveuploadrate="1"/>
117//
118// The positive upload rate is the percentage of uploads to send to the server
119// when something in the users profile matches what they have entered in a form.
120// The negative upload rate is the percentage of uploads to send when nothing in
121// the form matches what's in the users profile.
122// The negative upload rate is typically much lower than the positive upload
123// rate.
124class AutofillUploadXmlParser : public AutofillXmlParser {
125 public:
126  AutofillUploadXmlParser(double* positive_upload_rate,
127                          double* negative_upload_rate);
128
129 private:
130  // A callback for the beginning of a new <element>, called by Expat.
131  // |context| is a parsing context used to resolve element/attribute names.
132  // |name| is the name of the element.
133  // |attrs| is the list of attributes (names and values) for the element.
134  virtual void StartElement(buzz::XmlParseContext* context,
135                            const char* name,
136                            const char** attrs) OVERRIDE;
137
138  // A helper function to retrieve double values from strings.  Raises an XML
139  // parse error if it fails.
140  // |context| is the current parsing context.
141  // |value| is the string to convert.
142  double GetDoubleValue(buzz::XmlParseContext* context, const char* attribute);
143
144  // True if parsing succeeded.
145  bool succeeded_;
146
147  double* positive_upload_rate_;
148  double* negative_upload_rate_;
149
150  DISALLOW_COPY_AND_ASSIGN(AutofillUploadXmlParser);
151};
152
153}  // namespace autofill
154
155#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_XML_PARSER_H_
156