autofill_xml_parser.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2010 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.
4
5#include "chrome/browser/autofill/autofill_xml_parser.h"
6
7#include <string>
8#include <vector>
9
10#include "chrome/browser/autofill/autofill_type.h"
11#include "third_party/libjingle/overrides/talk/xmllite/qname.h"
12
13AutoFillXmlParser::AutoFillXmlParser()
14    : succeeded_(true) {
15}
16
17void AutoFillXmlParser::CharacterData(
18    buzz::XmlParseContext* context, const char* text, int len) {
19}
20
21void AutoFillXmlParser::EndElement(buzz::XmlParseContext* context,
22                                   const char* name) {
23}
24
25void AutoFillXmlParser::Error(buzz::XmlParseContext* context,
26                              XML_Error error_code) {
27  succeeded_ = false;
28}
29
30AutoFillQueryXmlParser::AutoFillQueryXmlParser(
31    std::vector<AutoFillFieldType>* field_types,
32    UploadRequired* upload_required)
33    : field_types_(field_types),
34      upload_required_(upload_required) {
35  DCHECK(upload_required_);
36}
37
38void AutoFillQueryXmlParser::StartElement(buzz::XmlParseContext* context,
39                                          const char* name,
40                                          const char** attrs) {
41  buzz::QName qname = context->ResolveQName(name, false);
42  const std::string &element = qname.LocalPart();
43  if (element.compare("autofillqueryresponse") == 0) {
44    // Check for the upload required attribute.  If it's not present, we use the
45    // default upload rates.
46    *upload_required_ = USE_UPLOAD_RATES;
47    if (*attrs) {
48      buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
49      const std::string &attribute_name = attribute_qname.LocalPart();
50      if (attribute_name.compare("uploadrequired") == 0) {
51        if (strcmp(attrs[1], "true") == 0)
52          *upload_required_ = UPLOAD_REQUIRED;
53        else if (strcmp(attrs[1], "false") == 0)
54          *upload_required_ = UPLOAD_NOT_REQUIRED;
55      }
56    }
57  } else if (element.compare("field") == 0) {
58    if (!attrs[0]) {
59      // Missing the "autofilltype" attribute, abort.
60      context->RaiseError(XML_ERROR_ABORTED);
61      return;
62    }
63
64    // Determine the field type from the attribute value.  There should be one
65    // attribute (autofilltype) with an integer value.
66    AutoFillFieldType field_type = UNKNOWN_TYPE;
67    buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
68    const std::string &attribute_name = attribute_qname.LocalPart();
69
70    if (attribute_name.compare("autofilltype") == 0) {
71      int value = GetIntValue(context, attrs[1]);
72      field_type = static_cast<AutoFillFieldType>(value);
73      if (field_type < 0 || field_type > MAX_VALID_FIELD_TYPE) {
74        field_type = NO_SERVER_DATA;
75      }
76    }
77
78    // Record this field type.
79    field_types_->push_back(field_type);
80  }
81}
82
83int AutoFillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context,
84                                        const char* attribute) {
85  char* attr_end = NULL;
86  int value = strtol(attribute, &attr_end, 10);
87  if (attr_end != NULL && attr_end == attribute) {
88    context->RaiseError(XML_ERROR_SYNTAX);
89    return 0;
90  }
91  return value;
92}
93
94AutoFillUploadXmlParser::AutoFillUploadXmlParser(double* positive_upload_rate,
95                                                 double* negative_upload_rate)
96    : positive_upload_rate_(positive_upload_rate),
97      negative_upload_rate_(negative_upload_rate) {
98  DCHECK(positive_upload_rate_);
99  DCHECK(negative_upload_rate_);
100}
101
102void AutoFillUploadXmlParser::StartElement(buzz::XmlParseContext* context,
103                                           const char* name,
104                                           const char** attrs) {
105  buzz::QName qname = context->ResolveQName(name, false);
106  const std::string &element = qname.LocalPart();
107  if (element.compare("autofilluploadresponse") == 0) {
108    // Loop over all attributes to get the upload rates.
109    while (*attrs) {
110      buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
111      const std::string &attribute_name = attribute_qname.LocalPart();
112      if (attribute_name.compare("positiveuploadrate") == 0) {
113        *positive_upload_rate_ = GetDoubleValue(context, attrs[1]);
114      } else if (attribute_name.compare("negativeuploadrate") == 0) {
115        *negative_upload_rate_ = GetDoubleValue(context, attrs[1]);
116      }
117      attrs += 2;  // We peeked at attrs[0] and attrs[1], skip past both.
118    }
119  }
120}
121
122double AutoFillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context,
123                                               const char* attribute) {
124  char* attr_end = NULL;
125  double value = strtod(attribute, &attr_end);
126  if (attr_end != NULL && attr_end == attribute) {
127    context->RaiseError(XML_ERROR_SYNTAX);
128    return 0.0;
129  }
130  return value;
131}
132