blob: b2e4c04c34f72fa4d0bcc71a82c5ebd22c093745 [file] [log] [blame]
[email protected]663bd9e2011-03-21 01:07:011// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]ec64212b2010-03-18 01:02:432// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/autofill/autofill_xml_parser.h"
6
[email protected]8f608c52011-03-30 16:16:317#include <stdlib.h>
8#include <string.h>
9
10#include "base/logging.h"
[email protected]732acb02013-01-22 17:04:4511#include "chrome/browser/autofill/autofill_server_field_info.h"
[email protected]0116cf52011-11-01 02:44:3212#include "third_party/libjingle/source/talk/xmllite/qname.h"
[email protected]ec64212b2010-03-18 01:02:4313
[email protected]663bd9e2011-03-21 01:07:0114AutofillXmlParser::AutofillXmlParser()
[email protected]ec64212b2010-03-18 01:02:4315 : succeeded_(true) {
16}
17
[email protected]663bd9e2011-03-21 01:07:0118void AutofillXmlParser::CharacterData(
[email protected]ec64212b2010-03-18 01:02:4319 buzz::XmlParseContext* context, const char* text, int len) {
20}
21
[email protected]663bd9e2011-03-21 01:07:0122void AutofillXmlParser::EndElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4323 const char* name) {
24}
25
[email protected]663bd9e2011-03-21 01:07:0126void AutofillXmlParser::Error(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4327 XML_Error error_code) {
28 succeeded_ = false;
29}
30
[email protected]663bd9e2011-03-21 01:07:0131AutofillQueryXmlParser::AutofillQueryXmlParser(
[email protected]732acb02013-01-22 17:04:4532 std::vector<AutofillServerFieldInfo>* field_infos,
[email protected]5f372f82011-01-31 23:20:5033 UploadRequired* upload_required,
34 std::string* experiment_id)
[email protected]732acb02013-01-22 17:04:4535 : field_infos_(field_infos),
[email protected]5f372f82011-01-31 23:20:5036 upload_required_(upload_required),
[email protected]e899b962013-01-18 20:52:0837 current_page_number_(-1),
38 total_pages_(-1),
[email protected]5f372f82011-01-31 23:20:5039 experiment_id_(experiment_id) {
[email protected]ec64212b2010-03-18 01:02:4340 DCHECK(upload_required_);
[email protected]5f372f82011-01-31 23:20:5041 DCHECK(experiment_id_);
[email protected]ec64212b2010-03-18 01:02:4342}
43
[email protected]663bd9e2011-03-21 01:07:0144void AutofillQueryXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4345 const char* name,
46 const char** attrs) {
47 buzz::QName qname = context->ResolveQName(name, false);
[email protected]5f372f82011-01-31 23:20:5048 const std::string& element = qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4349 if (element.compare("autofillqueryresponse") == 0) {
[email protected]5f372f82011-01-31 23:20:5050 // We check for the upload required attribute below, but if it's not
51 // present, we use the default upload rates. Likewise, by default we assume
52 // an empty experiment id.
[email protected]ec64212b2010-03-18 01:02:4353 *upload_required_ = USE_UPLOAD_RATES;
[email protected]5f372f82011-01-31 23:20:5054 *experiment_id_ = std::string();
55
56 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
57 while (*attrs) {
[email protected]732acb02013-01-22 17:04:4558 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
59 ++attrs;
[email protected]5f372f82011-01-31 23:20:5060 const std::string& attribute_name = attribute_qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4361 if (attribute_name.compare("uploadrequired") == 0) {
[email protected]732acb02013-01-22 17:04:4562 if (strcmp(*attrs, "true") == 0)
[email protected]ec64212b2010-03-18 01:02:4363 *upload_required_ = UPLOAD_REQUIRED;
[email protected]732acb02013-01-22 17:04:4564 else if (strcmp(*attrs, "false") == 0)
[email protected]ec64212b2010-03-18 01:02:4365 *upload_required_ = UPLOAD_NOT_REQUIRED;
[email protected]5f372f82011-01-31 23:20:5066 } else if (attribute_name.compare("experimentid") == 0) {
[email protected]732acb02013-01-22 17:04:4567 *experiment_id_ = *attrs;
[email protected]ec64212b2010-03-18 01:02:4368 }
[email protected]732acb02013-01-22 17:04:4569 ++attrs;
[email protected]ec64212b2010-03-18 01:02:4370 }
71 } else if (element.compare("field") == 0) {
[email protected]732acb02013-01-22 17:04:4572 if (!*attrs) {
[email protected]ec64212b2010-03-18 01:02:4373 // Missing the "autofilltype" attribute, abort.
74 context->RaiseError(XML_ERROR_ABORTED);
75 return;
76 }
77
78 // Determine the field type from the attribute value. There should be one
79 // attribute (autofilltype) with an integer value.
[email protected]732acb02013-01-22 17:04:4580 AutofillServerFieldInfo field_info;
81 field_info.field_type = UNKNOWN_TYPE;
[email protected]ec64212b2010-03-18 01:02:4382
[email protected]732acb02013-01-22 17:04:4583 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
84 while (*attrs) {
85 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
86 ++attrs;
87 const std::string& attribute_name = attribute_qname.LocalPart();
88 if (attribute_name.compare("autofilltype") == 0) {
89 int value = GetIntValue(context, *attrs);
90 if (value >= 0 && value < MAX_VALID_FIELD_TYPE)
91 field_info.field_type = static_cast<AutofillFieldType>(value);
92 else
93 field_info.field_type = NO_SERVER_DATA;
94 } else if (field_info.field_type == FIELD_WITH_DEFAULT_VALUE &&
95 attribute_name.compare("defaultvalue") == 0) {
96 field_info.default_value = *attrs;
[email protected]ec64212b2010-03-18 01:02:4397 }
[email protected]732acb02013-01-22 17:04:4598 ++attrs;
[email protected]ec64212b2010-03-18 01:02:4399 }
100
[email protected]732acb02013-01-22 17:04:45101 // Record this field type, default value pair.
102 field_infos_->push_back(field_info);
[email protected]e899b962013-01-18 20:52:08103 } else if (element.compare("autofill_flow") == 0) {
104 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
105 while (*attrs) {
106 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
107 ++attrs;
108 const std::string& attribute_name = attribute_qname.LocalPart();
109 if (attribute_name.compare("page_no") == 0)
110 current_page_number_ = GetIntValue(context, *attrs);
111 else if (attribute_name.compare("total_pages") == 0)
112 total_pages_ = GetIntValue(context, *attrs);
113 ++attrs;
114 }
[email protected]ec64212b2010-03-18 01:02:43115 }
116}
117
[email protected]663bd9e2011-03-21 01:07:01118int AutofillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43119 const char* attribute) {
120 char* attr_end = NULL;
121 int value = strtol(attribute, &attr_end, 10);
122 if (attr_end != NULL && attr_end == attribute) {
123 context->RaiseError(XML_ERROR_SYNTAX);
124 return 0;
125 }
126 return value;
127}
128
[email protected]663bd9e2011-03-21 01:07:01129AutofillUploadXmlParser::AutofillUploadXmlParser(double* positive_upload_rate,
[email protected]ec64212b2010-03-18 01:02:43130 double* negative_upload_rate)
[email protected]8cd7fd02010-07-22 18:21:02131 : succeeded_(false),
132 positive_upload_rate_(positive_upload_rate),
[email protected]ec64212b2010-03-18 01:02:43133 negative_upload_rate_(negative_upload_rate) {
134 DCHECK(positive_upload_rate_);
135 DCHECK(negative_upload_rate_);
136}
137
[email protected]663bd9e2011-03-21 01:07:01138void AutofillUploadXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43139 const char* name,
140 const char** attrs) {
141 buzz::QName qname = context->ResolveQName(name, false);
142 const std::string &element = qname.LocalPart();
143 if (element.compare("autofilluploadresponse") == 0) {
144 // Loop over all attributes to get the upload rates.
145 while (*attrs) {
146 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
147 const std::string &attribute_name = attribute_qname.LocalPart();
148 if (attribute_name.compare("positiveuploadrate") == 0) {
149 *positive_upload_rate_ = GetDoubleValue(context, attrs[1]);
150 } else if (attribute_name.compare("negativeuploadrate") == 0) {
151 *negative_upload_rate_ = GetDoubleValue(context, attrs[1]);
152 }
153 attrs += 2; // We peeked at attrs[0] and attrs[1], skip past both.
154 }
155 }
156}
157
[email protected]663bd9e2011-03-21 01:07:01158double AutofillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43159 const char* attribute) {
160 char* attr_end = NULL;
161 double value = strtod(attribute, &attr_end);
162 if (attr_end != NULL && attr_end == attribute) {
163 context->RaiseError(XML_ERROR_SYNTAX);
164 return 0.0;
165 }
166 return value;
167}