blob: 92a1ede91c0f94dbc96794d4060b2c51af488145 [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]7127ca8f2011-03-01 22:14:1831 std::vector<AutofillFieldType>* field_types,
[email protected]5f372f82011-01-31 23:20:5032 UploadRequired* upload_required,
33 std::string* experiment_id)
[email protected]ec64212b2010-03-18 01:02:4334 : field_types_(field_types),
[email protected]5f372f82011-01-31 23:20:5035 upload_required_(upload_required),
36 experiment_id_(experiment_id) {
[email protected]ec64212b2010-03-18 01:02:4337 DCHECK(upload_required_);
[email protected]5f372f82011-01-31 23:20:5038 DCHECK(experiment_id_);
[email protected]ec64212b2010-03-18 01:02:4339}
40
[email protected]663bd9e2011-03-21 01:07:0141void AutofillQueryXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4342 const char* name,
43 const char** attrs) {
44 buzz::QName qname = context->ResolveQName(name, false);
[email protected]5f372f82011-01-31 23:20:5045 const std::string& element = qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4346 if (element.compare("autofillqueryresponse") == 0) {
[email protected]5f372f82011-01-31 23:20:5047 // We check for the upload required attribute below, but if it's not
48 // present, we use the default upload rates. Likewise, by default we assume
49 // an empty experiment id.
[email protected]ec64212b2010-03-18 01:02:4350 *upload_required_ = USE_UPLOAD_RATES;
[email protected]5f372f82011-01-31 23:20:5051 *experiment_id_ = std::string();
52
53 // |attrs| is a NULL-terminated list of (attribute, value) pairs.
54 while (*attrs) {
[email protected]ec64212b2010-03-18 01:02:4355 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
[email protected]5f372f82011-01-31 23:20:5056 const std::string& attribute_name = attribute_qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4357 if (attribute_name.compare("uploadrequired") == 0) {
58 if (strcmp(attrs[1], "true") == 0)
59 *upload_required_ = UPLOAD_REQUIRED;
60 else if (strcmp(attrs[1], "false") == 0)
61 *upload_required_ = UPLOAD_NOT_REQUIRED;
[email protected]5f372f82011-01-31 23:20:5062 } else if (attribute_name.compare("experimentid") == 0) {
63 *experiment_id_ = attrs[1];
[email protected]ec64212b2010-03-18 01:02:4364 }
[email protected]5f372f82011-01-31 23:20:5065
66 // Advance to the next (attribute, value) pair.
67 attrs += 2;
[email protected]ec64212b2010-03-18 01:02:4368 }
69 } else if (element.compare("field") == 0) {
70 if (!attrs[0]) {
71 // Missing the "autofilltype" attribute, abort.
72 context->RaiseError(XML_ERROR_ABORTED);
73 return;
74 }
75
76 // Determine the field type from the attribute value. There should be one
77 // attribute (autofilltype) with an integer value.
[email protected]7127ca8f2011-03-01 22:14:1878 AutofillFieldType field_type = UNKNOWN_TYPE;
[email protected]ec64212b2010-03-18 01:02:4379 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
[email protected]5f372f82011-01-31 23:20:5080 const std::string& attribute_name = attribute_qname.LocalPart();
[email protected]ec64212b2010-03-18 01:02:4381
82 if (attribute_name.compare("autofilltype") == 0) {
83 int value = GetIntValue(context, attrs[1]);
[email protected]7127ca8f2011-03-01 22:14:1884 field_type = static_cast<AutofillFieldType>(value);
[email protected]ec64212b2010-03-18 01:02:4385 if (field_type < 0 || field_type > MAX_VALID_FIELD_TYPE) {
86 field_type = NO_SERVER_DATA;
87 }
88 }
89
90 // Record this field type.
91 field_types_->push_back(field_type);
92 }
93}
94
[email protected]663bd9e2011-03-21 01:07:0195int AutofillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:4396 const char* attribute) {
97 char* attr_end = NULL;
98 int value = strtol(attribute, &attr_end, 10);
99 if (attr_end != NULL && attr_end == attribute) {
100 context->RaiseError(XML_ERROR_SYNTAX);
101 return 0;
102 }
103 return value;
104}
105
[email protected]663bd9e2011-03-21 01:07:01106AutofillUploadXmlParser::AutofillUploadXmlParser(double* positive_upload_rate,
[email protected]ec64212b2010-03-18 01:02:43107 double* negative_upload_rate)
[email protected]8cd7fd02010-07-22 18:21:02108 : succeeded_(false),
109 positive_upload_rate_(positive_upload_rate),
[email protected]ec64212b2010-03-18 01:02:43110 negative_upload_rate_(negative_upload_rate) {
111 DCHECK(positive_upload_rate_);
112 DCHECK(negative_upload_rate_);
113}
114
[email protected]663bd9e2011-03-21 01:07:01115void AutofillUploadXmlParser::StartElement(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43116 const char* name,
117 const char** attrs) {
118 buzz::QName qname = context->ResolveQName(name, false);
119 const std::string &element = qname.LocalPart();
120 if (element.compare("autofilluploadresponse") == 0) {
121 // Loop over all attributes to get the upload rates.
122 while (*attrs) {
123 buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
124 const std::string &attribute_name = attribute_qname.LocalPart();
125 if (attribute_name.compare("positiveuploadrate") == 0) {
126 *positive_upload_rate_ = GetDoubleValue(context, attrs[1]);
127 } else if (attribute_name.compare("negativeuploadrate") == 0) {
128 *negative_upload_rate_ = GetDoubleValue(context, attrs[1]);
129 }
130 attrs += 2; // We peeked at attrs[0] and attrs[1], skip past both.
131 }
132 }
133}
134
[email protected]663bd9e2011-03-21 01:07:01135double AutofillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context,
[email protected]ec64212b2010-03-18 01:02:43136 const char* attribute) {
137 char* attr_end = NULL;
138 double value = strtod(attribute, &attr_end);
139 if (attr_end != NULL && attr_end == attribute) {
140 context->RaiseError(XML_ERROR_SYNTAX);
141 return 0.0;
142 }
143 return value;
144}