Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / autofill / core / browser / autofill_xml_parser.cc
blob6059b57791bdbd7c240941848a4592809b1fc064
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.
5 #include "components/autofill/core/browser/autofill_xml_parser.h"
7 #include <string.h>
9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "components/autofill/core/browser/autofill_server_field_info.h"
12 #include "third_party/webrtc/libjingle/xmllite/qname.h"
14 namespace autofill {
16 AutofillXmlParser::AutofillXmlParser()
17 : succeeded_(true) {
20 AutofillXmlParser::~AutofillXmlParser() {}
22 void AutofillXmlParser::CharacterData(
23 buzz::XmlParseContext* context, const char* text, int len) {
26 void AutofillXmlParser::EndElement(buzz::XmlParseContext* context,
27 const char* name) {
30 void AutofillXmlParser::Error(buzz::XmlParseContext* context,
31 XML_Error error_code) {
32 succeeded_ = false;
35 AutofillQueryXmlParser::AutofillQueryXmlParser(
36 std::vector<AutofillServerFieldInfo>* field_infos,
37 UploadRequired* upload_required)
38 : field_infos_(field_infos),
39 upload_required_(upload_required) {
40 DCHECK(upload_required_);
43 AutofillQueryXmlParser::~AutofillQueryXmlParser() {}
45 void AutofillQueryXmlParser::StartElement(buzz::XmlParseContext* context,
46 const char* name,
47 const char** attrs) {
48 buzz::QName qname = context->ResolveQName(name, false);
49 const std::string& element = qname.LocalPart();
50 if (element.compare("autofillqueryresponse") == 0) {
51 // We check for the upload required attribute below, but if it's not
52 // present, we use the default upload rates.
53 *upload_required_ = USE_UPLOAD_RATES;
55 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
56 while (*attrs) {
57 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
58 ++attrs;
59 const std::string& attribute_name = attribute_qname.LocalPart();
60 if (attribute_name.compare("uploadrequired") == 0) {
61 if (strcmp(*attrs, "true") == 0)
62 *upload_required_ = UPLOAD_REQUIRED;
63 else if (strcmp(*attrs, "false") == 0)
64 *upload_required_ = UPLOAD_NOT_REQUIRED;
66 ++attrs;
68 } else if (element.compare("field") == 0) {
69 if (!*attrs) {
70 // Missing the "autofilltype" attribute, abort.
71 context->RaiseError(XML_ERROR_ABORTED);
72 return;
75 // Determine the field type from the attribute value. There should be one
76 // attribute (autofilltype) with an integer value.
77 AutofillServerFieldInfo field_info;
78 field_info.field_type = UNKNOWN_TYPE;
80 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
81 while (*attrs) {
82 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
83 ++attrs;
84 const std::string& attribute_name = attribute_qname.LocalPart();
85 if (attribute_name.compare("autofilltype") == 0) {
86 int value = GetIntValue(context, *attrs);
87 if (value >= 0 && value < MAX_VALID_FIELD_TYPE)
88 field_info.field_type = static_cast<ServerFieldType>(value);
89 else
90 field_info.field_type = NO_SERVER_DATA;
91 } else if (field_info.field_type == FIELD_WITH_DEFAULT_VALUE &&
92 attribute_name.compare("defaultvalue") == 0) {
93 field_info.default_value = *attrs;
95 ++attrs;
98 // Record this field type, default value pair.
99 field_infos_->push_back(field_info);
103 void AutofillQueryXmlParser::ParseElementDescriptor(
104 buzz::XmlParseContext* context,
105 const char* const* attrs,
106 WebElementDescriptor* element_descriptor) {
107 // If both id and css_selector are set, the first one to appear will take
108 // precedence.
109 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
110 while (*attrs) {
111 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
112 ++attrs;
113 const std::string& attribute_name = attribute_qname.LocalPart();
114 buzz::QName value_qname = context->ResolveQName(*attrs, true);
115 ++attrs;
116 const std::string& attribute_value = value_qname.LocalPart();
117 if (attribute_name.compare("id") == 0 && !attribute_value.empty()) {
118 element_descriptor->retrieval_method = WebElementDescriptor::ID;
119 element_descriptor->descriptor = attribute_value;
120 break;
121 } else if (attribute_name.compare("css_selector") == 0 &&
122 !attribute_value.empty()) {
123 element_descriptor->retrieval_method = WebElementDescriptor::CSS_SELECTOR;
124 element_descriptor->descriptor = attribute_value;
125 break;
130 int AutofillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context,
131 const char* attribute) {
132 int value = 0;
133 if (!base::StringToInt(attribute, &value)) {
134 context->RaiseError(XML_ERROR_SYNTAX);
135 return 0;
137 return value;
140 AutofillUploadXmlParser::AutofillUploadXmlParser(double* positive_upload_rate,
141 double* negative_upload_rate)
142 : succeeded_(false),
143 positive_upload_rate_(positive_upload_rate),
144 negative_upload_rate_(negative_upload_rate) {
145 DCHECK(positive_upload_rate_);
146 DCHECK(negative_upload_rate_);
149 void AutofillUploadXmlParser::StartElement(buzz::XmlParseContext* context,
150 const char* name,
151 const char** attrs) {
152 buzz::QName qname = context->ResolveQName(name, false);
153 const std::string &element = qname.LocalPart();
154 if (element.compare("autofilluploadresponse") == 0) {
155 // Loop over all attributes to get the upload rates.
156 while (*attrs) {
157 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
158 const std::string &attribute_name = attribute_qname.LocalPart();
159 if (attribute_name.compare("positiveuploadrate") == 0) {
160 *positive_upload_rate_ = GetDoubleValue(context, attrs[1]);
161 } else if (attribute_name.compare("negativeuploadrate") == 0) {
162 *negative_upload_rate_ = GetDoubleValue(context, attrs[1]);
164 attrs += 2; // We peeked at attrs[0] and attrs[1], skip past both.
169 double AutofillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context,
170 const char* attribute) {
171 double value = 0;
172 if (!base::StringToDouble(attribute, &value)) {
173 context->RaiseError(XML_ERROR_SYNTAX);
174 return 0.0;
176 return value;
179 } // namespace autofill