blob: 425185b75382cf9c5283a1a943244501cbb70d70 [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]0116cf52011-11-01 02:44:3211#include "third_party/libjingle/source/talk/xmllite/qname.h"
[email protected]ec64212b2010-03-18 01:02:4312
[email protected]663bd9e2011-03-21 01:07:0113AutofillXmlParser::AutofillXmlParser()
[email protected]ec64212b2010-03-18 01:02:4314 : succeeded_(true) {
15}
16
[email protected]663bd9e2011-03-21 01:07:0117void AutofillXmlParser::CharacterData(
[email protected]ec64212b2010-03-18 01:02:4318 buzz::XmlParseContext* context, const char* text, int len) {
19}
20
[email protected]663bd9e2011-03-21 01:07:0121void AutofillXmlParser::EndElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4322 const char* name) {
23}
24
[email protected]663bd9e2011-03-21 01:07:0125void AutofillXmlParser::Error(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4326 XML_Error error_code) {
27 succeeded_ = false;
28}
29
[email protected]663bd9e2011-03-21 01:07:0130AutofillQueryXmlParser::AutofillQueryXmlParser(
[email protected]606d10802013-01-14 18:14:5731 std::vector<AutofillFieldType>* field_types,
[email protected]5f372f82011-01-31 23:20:5032 UploadRequired* upload_required,
33 std::string* experiment_id)
[email protected]606d10802013-01-14 18:14:5734 : field_types_(field_types),
[email protected]5f372f82011-01-31 23:20:5035 upload_required_(upload_required),
[email protected]e899b962013-01-18 20:52:0836 current_page_number_(-1),
37 total_pages_(-1),
[email protected]5f372f82011-01-31 23:20:5038 experiment_id_(experiment_id) {
[email protected]ec64212b2010-03-18 01:02:4339 DCHECK(upload_required_);
[email protected]5f372f82011-01-31 23:20:5040 DCHECK(experiment_id_);
[email protected]ec64212b2010-03-18 01:02:4341}
42
[email protected]663bd9e2011-03-21 01:07:0143void AutofillQueryXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4344 const char* name,
45 const char** attrs) {
46 buzz::QName qname = context->ResolveQName(name, false);
[email protected]5f372f82011-01-31 23:20:5047 const std::string& element = qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4348 if (element.compare("autofillqueryresponse") == 0) {
[email protected]5f372f82011-01-31 23:20:5049 // We check for the upload required attribute below, but if it's not
50 // present, we use the default upload rates. Likewise, by default we assume
51 // an empty experiment id.
[email protected]ec64212b2010-03-18 01:02:4352 *upload_required_ = USE_UPLOAD_RATES;
[email protected]5f372f82011-01-31 23:20:5053 *experiment_id_ = std::string();
54
55 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
56 while (*attrs) {
[email protected]606d10802013-01-14 18:14:5757 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
[email protected]5f372f82011-01-31 23:20:5058 const std::string& attribute_name = attribute_qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4359 if (attribute_name.compare("uploadrequired") == 0) {
[email protected]606d10802013-01-14 18:14:5760 if (strcmp(attrs[1], "true") == 0)
[email protected]ec64212b2010-03-18 01:02:4361 *upload_required_ = UPLOAD_REQUIRED;
[email protected]606d10802013-01-14 18:14:5762 else if (strcmp(attrs[1], "false") == 0)
[email protected]ec64212b2010-03-18 01:02:4363 *upload_required_ = UPLOAD_NOT_REQUIRED;
[email protected]5f372f82011-01-31 23:20:5064 } else if (attribute_name.compare("experimentid") == 0) {
[email protected]606d10802013-01-14 18:14:5765 *experiment_id_ = attrs[1];
[email protected]ec64212b2010-03-18 01:02:4366 }
[email protected]606d10802013-01-14 18:14:5767
68 // Advance to the next (attribute, value) pair.
69 attrs += 2;
[email protected]ec64212b2010-03-18 01:02:4370 }
71 } else if (element.compare("field") == 0) {
[email protected]606d10802013-01-14 18:14:5772 if (!attrs[0]) {
[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]606d10802013-01-14 18:14:5780 AutofillFieldType field_type = UNKNOWN_TYPE;
81 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
82 const std::string& attribute_name = attribute_qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4383
[email protected]606d10802013-01-14 18:14:5784 if (attribute_name.compare("autofilltype") == 0) {
85 int value = GetIntValue(context, attrs[1]);
86 field_type = static_cast<AutofillFieldType>(value);
87 if (field_type < 0 || field_type > MAX_VALID_FIELD_TYPE) {
88 field_type = NO_SERVER_DATA;
[email protected]ec64212b2010-03-18 01:02:4389 }
90 }
91
[email protected]606d10802013-01-14 18:14:5792 // Record this field type.
93 field_types_->push_back(field_type);
[email protected]e899b962013-01-18 20:52:0894 } else if (element.compare("autofill_flow") == 0) {
95 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
96 while (*attrs) {
97 buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
98 ++attrs;
99 const std::string& attribute_name = attribute_qname.LocalPart();
100 if (attribute_name.compare("page_no") == 0)
101 current_page_number_ = GetIntValue(context, *attrs);
102 else if (attribute_name.compare("total_pages") == 0)
103 total_pages_ = GetIntValue(context, *attrs);
104 ++attrs;
105 }
[email protected]ec64212b2010-03-18 01:02:43106 }
107}
108
[email protected]663bd9e2011-03-21 01:07:01109int AutofillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43110 const char* attribute) {
111 char* attr_end = NULL;
112 int value = strtol(attribute, &attr_end, 10);
113 if (attr_end != NULL && attr_end == attribute) {
114 context->RaiseError(XML_ERROR_SYNTAX);
115 return 0;
116 }
117 return value;
118}
119
[email protected]663bd9e2011-03-21 01:07:01120AutofillUploadXmlParser::AutofillUploadXmlParser(double* positive_upload_rate,
[email protected]ec64212b2010-03-18 01:02:43121 double* negative_upload_rate)
[email protected]8cd7fd02010-07-22 18:21:02122 : succeeded_(false),
123 positive_upload_rate_(positive_upload_rate),
[email protected]ec64212b2010-03-18 01:02:43124 negative_upload_rate_(negative_upload_rate) {
125 DCHECK(positive_upload_rate_);
126 DCHECK(negative_upload_rate_);
127}
128
[email protected]663bd9e2011-03-21 01:07:01129void AutofillUploadXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43130 const char* name,
131 const char** attrs) {
132 buzz::QName qname = context->ResolveQName(name, false);
133 const std::string &element = qname.LocalPart();
134 if (element.compare("autofilluploadresponse") == 0) {
135 // Loop over all attributes to get the upload rates.
136 while (*attrs) {
137 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
138 const std::string &attribute_name = attribute_qname.LocalPart();
139 if (attribute_name.compare("positiveuploadrate") == 0) {
140 *positive_upload_rate_ = GetDoubleValue(context, attrs[1]);
141 } else if (attribute_name.compare("negativeuploadrate") == 0) {
142 *negative_upload_rate_ = GetDoubleValue(context, attrs[1]);
143 }
144 attrs += 2; // We peeked at attrs[0] and attrs[1], skip past both.
145 }
146 }
147}
148
[email protected]663bd9e2011-03-21 01:07:01149double AutofillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43150 const char* attribute) {
151 char* attr_end = NULL;
152 double value = strtod(attribute, &attr_end);
153 if (attr_end != NULL && attr_end == attribute) {
154 context->RaiseError(XML_ERROR_SYNTAX);
155 return 0.0;
156 }
157 return value;
158}