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