Home | History | Annotate | Download | only in metrics
      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*
     17 inline const char* Char(const xmlChar* input) {
     18   return reinterpret_cast<const char*>(input);
     19 }
     20 
     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 
     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