• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2006-2008 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/metrics/metrics_response.h"
6 
7 #include "libxml/parser.h"
8 
9 // State to pass around during SAX parsing.
10 struct SAXState {
11   int collectors;
12   int events;
13   int interval;
14 };
15 
16 // libxml uses xmlChar*, which is unsigned char*
Char(const xmlChar * input)17 inline const char* Char(const xmlChar* input) {
18   return reinterpret_cast<const char*>(input);
19 }
20 
SAXStartElement(void * user_data,const xmlChar * name,const xmlChar ** attrs)21 static void SAXStartElement(void* user_data,
22                             const xmlChar* name,
23                             const xmlChar** attrs) {
24   if (!name || !attrs)
25     return;
26 
27   SAXState* state = static_cast<SAXState*>(user_data);
28 
29   if (strcmp(Char(name), "upload") == 0) {
30     for (int i = 0; attrs[i] && attrs[i + i]; i += 2) {
31       if (strcmp(Char(attrs[i]), "interval") == 0) {
32         state->interval = atoi(Char(attrs[i + 1]));
33         return;
34       }
35     }
36   } else if (strcmp(Char(name), "limit") == 0) {
37     for (int i = 0; attrs[i] && attrs[i + 1]; i += 2) {
38       if (strcmp(Char(attrs[i]), "events") == 0) {
39         state->events = atoi(Char(attrs[i + 1]));
40         return;
41       }
42     }
43   } else if (strcmp(Char(name), "collector") == 0) {
44     for (int i = 0; attrs[i] && attrs[i + 1]; i += 2) {
45       if (strcmp(Char(attrs[i]), "type") == 0) {
46         const char* type = Char(attrs[i + 1]);
47         if (strcmp(type, "document") == 0) {
48           state->collectors |= MetricsResponse::COLLECTOR_DOCUMENT;
49         } else if (strcmp(type, "profile") == 0) {
50           state->collectors |= MetricsResponse::COLLECTOR_PROFILE;
51         } else if (strcmp(type, "window") == 0) {
52           state->collectors |= MetricsResponse::COLLECTOR_WINDOW;
53         } else if (strcmp(type, "ui") == 0) {
54           state->collectors |= MetricsResponse::COLLECTOR_UI;
55         }
56         return;
57       }
58     }
59   }
60 }
61 
MetricsResponse(const std::string & response_xml)62 MetricsResponse::MetricsResponse(const std::string& response_xml)
63     : valid_(false),
64       collectors_(COLLECTOR_NONE),
65       events_(0),
66       interval_(0) {
67   if (response_xml.empty())
68     return;
69 
70   xmlSAXHandler handler = {0};
71   handler.startElement = SAXStartElement;
72   SAXState state = {0};
73 
74   valid_ = !xmlSAXUserParseMemory(&handler, &state,
75                                   response_xml.data(),
76                                   static_cast<int>(response_xml.size()));
77 
78   collectors_ = state.collectors;
79   events_ = state.events;
80   interval_ = state.interval;
81 }
82