1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/metrics/metrics_response.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "libxml/parser.h"
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// State to pass around during SAX parsing.
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SAXState {
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int collectors;
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int events;
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int interval;
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// libxml uses xmlChar*, which is unsigned char*
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline const char* Char(const xmlChar* input) {
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return reinterpret_cast<const char*>(input);
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void SAXStartElement(void* user_data,
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const xmlChar* name,
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const xmlChar** attrs) {
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!name || !attrs)
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SAXState* state = static_cast<SAXState*>(user_data);
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (strcmp(Char(name), "upload") == 0) {
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; attrs[i] && attrs[i + i]; i += 2) {
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (strcmp(Char(attrs[i]), "interval") == 0) {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        state->interval = atoi(Char(attrs[i + 1]));
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (strcmp(Char(name), "limit") == 0) {
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; attrs[i] && attrs[i + 1]; i += 2) {
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (strcmp(Char(attrs[i]), "events") == 0) {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        state->events = atoi(Char(attrs[i + 1]));
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (strcmp(Char(name), "collector") == 0) {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; attrs[i] && attrs[i + 1]; i += 2) {
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (strcmp(Char(attrs[i]), "type") == 0) {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        const char* type = Char(attrs[i + 1]);
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (strcmp(type, "document") == 0) {
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          state->collectors |= MetricsResponse::COLLECTOR_DOCUMENT;
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        } else if (strcmp(type, "profile") == 0) {
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          state->collectors |= MetricsResponse::COLLECTOR_PROFILE;
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        } else if (strcmp(type, "window") == 0) {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          state->collectors |= MetricsResponse::COLLECTOR_WINDOW;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        } else if (strcmp(type, "ui") == 0) {
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          state->collectors |= MetricsResponse::COLLECTOR_UI;
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMetricsResponse::MetricsResponse(const std::string& response_xml)
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : valid_(false),
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      collectors_(COLLECTOR_NONE),
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      events_(0),
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      interval_(0) {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (response_xml.empty())
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  xmlSAXHandler handler = {0};
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handler.startElement = SAXStartElement;
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SAXState state = {0};
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  valid_ = !xmlSAXUserParseMemory(&handler, &state,
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  response_xml.data(),
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  static_cast<int>(response_xml.size()));
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  collectors_ = state.collectors;
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  events_ = state.events;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interval_ = state.interval;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
82