blob: 4dd2f1c4b808a3bf65ee67295805185f8783b8e9 [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]ec64212b2010-03-18 01:02:437#include "chrome/browser/autofill/autofill_type.h"
[email protected]7b7a16b2010-06-03 04:08:188#include "third_party/libjingle/overrides/talk/xmllite/qname.h"
[email protected]ec64212b2010-03-18 01:02:439
[email protected]663bd9e2011-03-21 01:07:0110AutofillXmlParser::AutofillXmlParser()
[email protected]ec64212b2010-03-18 01:02:4311 : succeeded_(true) {
12}
13
[email protected]663bd9e2011-03-21 01:07:0114void AutofillXmlParser::CharacterData(
[email protected]ec64212b2010-03-18 01:02:4315 buzz::XmlParseContext* context, const char* text, int len) {
16}
17
[email protected]663bd9e2011-03-21 01:07:0118void AutofillXmlParser::EndElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4319 const char* name) {
20}
21
[email protected]663bd9e2011-03-21 01:07:0122void AutofillXmlParser::Error(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4323 XML_Error error_code) {
24 succeeded_ = false;
25}
26
[email protected]663bd9e2011-03-21 01:07:0127AutofillQueryXmlParser::AutofillQueryXmlParser(
[email protected]7127ca8f2011-03-01 22:14:1828 std::vector<AutofillFieldType>* field_types,
[email protected]5f372f82011-01-31 23:20:5029 UploadRequired* upload_required,
30 std::string* experiment_id)
[email protected]ec64212b2010-03-18 01:02:4331 : field_types_(field_types),
[email protected]5f372f82011-01-31 23:20:5032 upload_required_(upload_required),
33 experiment_id_(experiment_id) {
[email protected]ec64212b2010-03-18 01:02:4334 DCHECK(upload_required_);
[email protected]5f372f82011-01-31 23:20:5035 DCHECK(experiment_id_);
[email protected]ec64212b2010-03-18 01:02:4336}
37
[email protected]663bd9e2011-03-21 01:07:0138void AutofillQueryXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4339 const char* name,
40 const char** attrs) {
41 buzz::QName qname = context->ResolveQName(name, false);
[email protected]5f372f82011-01-31 23:20:5042 const std::string& element = qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4343 if (element.compare("autofillqueryresponse") == 0) {
[email protected]5f372f82011-01-31 23:20:5044 // We check for the upload required attribute below, but if it's not
45 // present, we use the default upload rates. Likewise, by default we assume
46 // an empty experiment id.
[email protected]ec64212b2010-03-18 01:02:4347 *upload_required_ = USE_UPLOAD_RATES;
[email protected]5f372f82011-01-31 23:20:5048 *experiment_id_ = std::string();
49
50 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
51 while (*attrs) {
[email protected]ec64212b2010-03-18 01:02:4352 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
[email protected]5f372f82011-01-31 23:20:5053 const std::string& attribute_name = attribute_qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4354 if (attribute_name.compare("uploadrequired") == 0) {
55 if (strcmp(attrs[1], "true") == 0)
56 *upload_required_ = UPLOAD_REQUIRED;
57 else if (strcmp(attrs[1], "false") == 0)
58 *upload_required_ = UPLOAD_NOT_REQUIRED;
[email protected]5f372f82011-01-31 23:20:5059 } else if (attribute_name.compare("experimentid") == 0) {
60 *experiment_id_ = attrs[1];
[email protected]ec64212b2010-03-18 01:02:4361 }
[email protected]5f372f82011-01-31 23:20:5062
63 // Advance to the next (attribute, value) pair.
64 attrs += 2;
[email protected]ec64212b2010-03-18 01:02:4365 }
66 } else if (element.compare("field") == 0) {
67 if (!attrs[0]) {
68 // Missing the "autofilltype" attribute, abort.
69 context->RaiseError(XML_ERROR_ABORTED);
70 return;
71 }
72
73 // Determine the field type from the attribute value. There should be one
74 // attribute (autofilltype) with an integer value.
[email protected]7127ca8f2011-03-01 22:14:1875 AutofillFieldType field_type = UNKNOWN_TYPE;
[email protected]ec64212b2010-03-18 01:02:4376 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
[email protected]5f372f82011-01-31 23:20:5077 const std::string& attribute_name = attribute_qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4378
79 if (attribute_name.compare("autofilltype") == 0) {
80 int value = GetIntValue(context, attrs[1]);
[email protected]7127ca8f2011-03-01 22:14:1881 field_type = static_cast<AutofillFieldType>(value);
[email protected]ec64212b2010-03-18 01:02:4382 if (field_type < 0 || field_type > MAX_VALID_FIELD_TYPE) {
83 field_type = NO_SERVER_DATA;
84 }
85 }
86
87 // Record this field type.
88 field_types_->push_back(field_type);
89 }
90}
91
[email protected]663bd9e2011-03-21 01:07:0192int AutofillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4393 const char* attribute) {
94 char* attr_end = NULL;
95 int value = strtol(attribute, &attr_end, 10);
96 if (attr_end != NULL && attr_end == attribute) {
97 context->RaiseError(XML_ERROR_SYNTAX);
98 return 0;
99 }
100 return value;
101}
102
[email protected]663bd9e2011-03-21 01:07:01103AutofillUploadXmlParser::AutofillUploadXmlParser(double* positive_upload_rate,
[email protected]ec64212b2010-03-18 01:02:43104 double* negative_upload_rate)
[email protected]8cd7fd02010-07-22 18:21:02105 : succeeded_(false),
106 positive_upload_rate_(positive_upload_rate),
[email protected]ec64212b2010-03-18 01:02:43107 negative_upload_rate_(negative_upload_rate) {
108 DCHECK(positive_upload_rate_);
109 DCHECK(negative_upload_rate_);
110}
111
[email protected]663bd9e2011-03-21 01:07:01112void AutofillUploadXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43113 const char* name,
114 const char** attrs) {
115 buzz::QName qname = context->ResolveQName(name, false);
116 const std::string &element = qname.LocalPart();
117 if (element.compare("autofilluploadresponse") == 0) {
118 // Loop over all attributes to get the upload rates.
119 while (*attrs) {
120 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
121 const std::string &attribute_name = attribute_qname.LocalPart();
122 if (attribute_name.compare("positiveuploadrate") == 0) {
123 *positive_upload_rate_ = GetDoubleValue(context, attrs[1]);
124 } else if (attribute_name.compare("negativeuploadrate") == 0) {
125 *negative_upload_rate_ = GetDoubleValue(context, attrs[1]);
126 }
127 attrs += 2; // We peeked at attrs[0] and attrs[1], skip past both.
128 }
129 }
130}
131
[email protected]663bd9e2011-03-21 01:07:01132double AutofillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43133 const char* attribute) {
134 char* attr_end = NULL;
135 double value = strtod(attribute, &attr_end);
136 if (attr_end != NULL && attr_end == attribute) {
137 context->RaiseError(XML_ERROR_SYNTAX);
138 return 0.0;
139 }
140 return value;
141}